Lời tựa

Về LeetCode

Nhắc đến LeetCode, đối với một lập trình viên thì chắc hẳn không hề xa lạ. Trong vài năm gần đây, khi tham gia phỏng vấn gần như đều sẽ nhắc tới nó. Lập trình viên trong và ngoài nước sử dụng LeetCode để luyện bài chủ yếu phục vụ cho mục đích phỏng vấn. Theo ghi chép lịch sử, website này được thành lập từ năm 2011, và sắp sửa bước sang sinh nhật lần thứ 10 của mình.

LeetCode tổ chức các cuộc thi hàng tuần, thi hai tuần một lần, và thi hàng tháng. Việc phải code trong thời gian giới hạn thực sự là một thử thách rất lớn đối với năng lực thuật toán của mỗi người. Một số cuộc thi còn được các công ty lớn tài trợ, những người đạt thứ hạng cao không chỉ nhận được phần thưởng mà còn có cơ hội nhận được thư giới thiệu nội bộ trực tiếp.

Cookbook là gì

Nếu dịch sát nghĩa thì đó là “sách nấu ăn” – một cuốn sách dạy bạn cách chế biến các món ăn theo công thức. Những ai thường xuyên đọc sách kỹ thuật của O'Reilly chắc chắn sẽ rất quen thuộc với thuật ngữ này. Thông thường, các cuốn sách thiên về thực hành, thao tác trực tiếp đều hay sử dụng cái tên này.

logo

Vì sao lại viết cuốn sách mã nguồn mở này

Tác giả đã luyện LeetCode được hơn một năm, và muốn chia sẻ với mọi người một số kinh nghiệm làm bài cũng như phương pháp giải. Đồng thời cũng mong muốn kết giao thêm những người có cùng sở thích, cùng nhau trao đổi và học tập.

Đối với bản thân tác giả, việc viết lời giải cũng là một cách để nâng cao năng lực. Có thể giảng giải một bài toán khó hiểu cho một người hoàn toàn chưa có manh mối, và khiến họ hiểu rõ ràng, là một cách rèn luyện rất tốt khả năng diễn đạt. Trong quá trình giảng giải, rất có thể sẽ gặp phải những câu hỏi từ người nghe, mà chính những câu hỏi đó lại phơi bày ra lỗ hổng kiến thức của bản thân, buộc mình phải đi bù đắp.

Tác giả cũng từng chia sẻ nội dung tương tự trong công ty và cảm nhận rất rõ: cả người chia sẻ lẫn người nghe đều thu được lợi ích đáng kể.

Ngoài ra, khi còn học đại học, tác giả cực kỳ ghét việc viết lời giải, luôn cảm thấy đó là lãng phí thời gian, thà dùng thời gian đó để làm thêm nhiều bài hơn. Bây giờ không biết có được gọi là “ra đời rồi, kiểu gì cũng phải trả nợ” hay không.

Về bìa sách

Những ai thường xuyên đọc “sách động vật” của O'Reilly chắc hẳn nhìn bìa là nhận ra ngay – đây chính là một sự tri ân dành cho họ. Quả thực, đó cũng chính là mục đích.

Các con vật trên bìa sách O'Reilly đều là động vật quý hiếm, và phong cách vẽ đều là tranh phác thảo đen trắng. Do các hình ảnh đó đều có bản quyền, nên tác giả chỉ có thể tìm những hình vẽ đen trắng không có bản quyền trên mạng. Thông thường chỉ có thể tìm được khoảng 40 hình theo phong cách này, nhưng vì quá nhiều người sử dụng nên tác giả đã rất vất vả tìm thêm những hình khác. Hình chim công xòe đuôi này là một trong số đó.

Ý nghĩa của hình chim công xòe đuôi là hy vọng rằng sau khi mọi người luyện xong LeetCode, năng lực thuật toán của bản thân được nâng cao, và có thể “xòe cánh” trên sân khấu cuộc đời của chính mình. Toàn bộ sách cũng sử dụng tông màu xanh lá, bởi vì đó là màu của AC.

Về tác giả

Tác giả là một gopher mới vào nghề được khoảng một năm rưỡi, mong các tiền bối chỉ giáo thêm. Trong thời gian đại học, tác giả đã tham gia ACM-ICPC suốt 3 năm, nhưng do năng lực còn hạn chế nên không giành được huy chương vàng nào. Vì vậy, trong lĩnh vực thuật toán, tác giả tự đánh giá mình vẫn là người mới.

Thu hoạch lớn nhất từ ACM-ICPC chính là rèn luyện được tư duy, và khả năng này cũng được áp dụng rất nhiều trong cuộc sống. Thứ hai là được gặp gỡ rất nhiều tuyển thủ thông minh trong nước, từ đó thấy rõ khoảng cách giữa bản thân và họ. Cuối cùng là hơn 200 trang template thuật toán được in dày đặc, mà có những phần đến nay tác giả vẫn chưa hoàn toàn hiểu hết.

Kiến thức nếu học được thì sẽ theo ta suốt đời, còn nếu chưa học được, thì dù có ghi chép lại cũng chỉ là thứ bên ngoài.

Tác giả bắt đầu luyện LeetCode từ ngày 25/03/2019 đến 25/03/2020, tròn một năm. Kế hoạch ban đầu là mỗi ngày một bài. Trên thực tế có những ngày làm hơn một bài, cuối cùng hoàn thành hơn 600 bài:

Một lời nhắc nho nhỏ: ban đầu tác giả cứ nghĩ rằng mỗi ngày làm một bài thì biểu đồ submissions sẽ toàn màu xanh, nhưng sau đó mới phát hiện mình đã nhầm. Nếu bạn cũng muốn kiên trì để “phủ xanh” biểu đồ này, nhất định phải chú ý một điểm sau: server của LeetCode sử dụng múi giờ +0, và biểu đồ này cũng được tính theo múi giờ đó. Điều này có nghĩa là ở Trung Quốc, trước 8 giờ sáng thì vẫn được tính là ngày hôm trước!

Chính vì vấn đề múi giờ này mà biểu đồ của tác giả bị trống mất 22 ô. Ví dụ có những bài Hard rất khó, hôm đó công việc cũng nhiều, sau khi tan làm về nhà nghĩ ra lời giải thì đã sang rạng sáng hôm sau. Lúc này lại làm thêm một bài coi như chỉ tiêu của ngày hôm sau, kết quả là cả 2 bài đều bị tính cho ngày hôm trước. Có lúc tác giả dậy lúc 6 giờ sáng để luyện bài, nhưng submit xong vẫn bị tính là ngày hôm trước.

(Dù sao thì đó cũng là chuyện đã qua, không còn quan trọng nữa, cứ coi như một vài khúc quanh nho nhỏ trên con đường phấn đấu vậy.)

Năm 2020, tác giả chắc chắn vẫn sẽ tiếp tục luyện bài, bởi vì vẫn chưa đạt được một số mục tiêu của bản thân. Có thể sẽ tiến tới mốc 1000 bài, hoặc cũng có thể đến khoảng 800 bài thì quay lại làm lần hai, lần ba. (Không đạt mục tiêu thì không dừng lại~)

Về code trong sách

Toàn bộ code đều được đặt trong github repo, có thể tìm bài theo số thứ tự câu hỏi.
Tất cả các bài trong sách này đều đạt beats 100%. Những bài chưa đạt beats 100% thì sẽ không được đưa vào sách. Tác giả sẽ tiếp tục tối ưu cho đến khi đạt 100% rồi mới bổ sung.

Có thể sẽ có độc giả thắc mắc: vì sao lại phải theo đuổi beats 100%? Tác giả cho rằng, chỉ khi tối ưu đến mức beats 100% thì mới thực sự “làm ra hồn” một bài toán. Có không ít bài Hard, tác giả dùng brute force vẫn AC, nhưng chỉ beats được 5%, những bài như vậy chẳng khác gì chưa làm. Nếu trong phỏng vấn mà đưa ra lời giải như thế, người phỏng vấn cũng sẽ không hài lòng, và chắc chắn sẽ hỏi: “Còn cách nào tối ưu hơn không?”. Nếu thông qua suy nghĩ của bản thân mà đưa ra được lời giải tốt hơn, chắc chắn sẽ ghi điểm nhiều hơn.

Thống kê thời gian chạy code của LeetCode cũng có độ dao động. Cùng một đoạn code, submit 10 lần có khi sẽ beats 100%. Ban đầu tác giả không nhận ra vấn đề này, nên có nhiều bài dùng code đúng submit liên tục rất nhiều lần. Trong một năm submit hơn 3400 lần, dẫn đến tỷ lệ đúng của bản thân cũng tăng vọt. 😢

Tất nhiên, nếu có những lời giải khác đẹp hơn, và cũng đạt beats 100%, rất hoan nghênh mọi người gửi PR, để tác giả cùng học hỏi với mọi người.

Đối tượng độc giả

Những người yêu thích lập trình, mong muốn nâng cao năng lực thuật toán thông qua LeetCode.

Ngôn ngữ lập trình

Toàn bộ thuật toán trong sách đều được cài đặt bằng ngôn ngữ Go.

Hướng dẫn sử dụng

  • Góc trên bên trái của sách điện tử có thanh tìm kiếm, giúp bạn nhanh chóng tìm được chương hoặc câu hỏi mong muốn.
  • Mỗi trang trong sách đều được tích hợp Gitalk, phía dưới cùng của mỗi trang đều có khung bình luận. Nếu không hiển thị, vui lòng kiểm tra kết nối mạng.
  • Về cách sử dụng lời giải, tác giả khuyên bạn nên làm như sau:
    Trước tiên hãy tự đọc đề và suy nghĩ cách giải. Nếu sau 15 phút vẫn chưa có ý tưởng, hãy xem phần tư duy giải bài của tác giả, nhưng đừng xem code. Sau khi có ý tưởng, hãy tự mình cài đặt lại bằng code. Nếu hoàn toàn không viết được, lúc đó mới xem code của tác giả, tìm ra chỗ mình không biết viết như thế nào, ghi chú lại – đó chính là lỗ hổng kiến thức cần bù đắp.
    Nếu tự viết ra được nhưng submit bị lỗi, hãy tự debug trước. Sau khi AC mà chưa đạt 100%, hãy tiếp tục suy nghĩ cách tối ưu. Nếu mỗi bài bạn đều có thể tối ưu đến 100%, thì sau một thời gian, tiến bộ sẽ rất rõ rệt.
    Tóm lại: thật sự không có ý tưởng thì xem tư duy; thật sự không tối ưu được thì xem code.

Tương tác và đính chính

Nếu trong sách có nội dung thiếu sót, hoan nghênh bạn nhấn nút edit ở cuối trang để bình luận và trao đổi. Xin cảm ơn sự ủng hộ và giúp đỡ của bạn.

Lời kết

Cùng nhau bắt đầu luyện LeetCode thôi~

Tác phẩm này được phát hành theo giấy phép
Creative Commons Attribution-NonCommercial-NoDerivatives (BY-NC-ND) 4.0 International

Toàn bộ bản quyền các bài toán trong phần lời giải đều thuộc về
LeetCodeLeetCode Trung Quốc