← Cấu trúc dữ liệu & Giải thuật← Data Structures & Algorithms
Cấu trúc dữ liệu & Giải thuậtData Structures & Algorithms7 Th8, 2026Aug 7, 202625 phút đọc20 min read

Nền tảng luyện tập & Chuẩn bị phỏng vấnPlatforms to Practice & Interview Preparation

Mục lục
  1. Tổng quan
  2. Kiến thức nền tảng
  3. Các nền tảng, và mỗi cái thực sự dùng để làm gì
  4. Vòng lặp luyện tập
  5. Timebox, và vì sao việc vật lộn cũng có giới hạn
  6. Khái niệm chính
  7. Thứ tự đề xuất đi qua section này
  8. Danh sách pattern
  9. Giao tiếp trong buổi phỏng vấn kỹ thuật
  10. Những kiểu thất bại thường gặp
  11. Tuần cuối trước buổi phỏng vấn
  12. Best Practices
  13. Tài liệu tham khảo
Table of contents
  1. Overview
  2. Fundamentals
  3. The platforms, and what each is actually for
  4. The practice loop
  5. Timeboxing, and why struggling has a limit
  6. Key Concepts
  7. A suggested order through this section
  8. The pattern list
  9. Communicating in a technical interview
  10. Common failure modes
  11. The last week before an interview
  12. Best Practices
  13. References

Thuộc bộ kiến thức Data Structures & Algorithms Roadmap.

Tổng quan

Toàn bộ hai mươi ba topic trước là kiến thức bạn có thể thu nạp bằng cách đọc. Topic này thì không. Data structures và algorithms là một kỹ năng, mà kỹ năng thì chỉ có được bằng cách làm dở, nhận phản hồi, rồi làm lại — chứ không phải bằng cách đọc về những người làm giỏi.

Sai lầm gần như ai cũng mắc là coi việc luyện tập như một bài toán số lượng: “tôi sẽ làm 300 bài”. Số lượng mà không có cấu trúc sẽ tạo ra những người đã nhìn qua 300 bài và giải được khoảng 40 bài, vì 260 bài còn lại họ “giải” bằng cách đọc editorial sau hai mươi phút rồi thấy như mình đã hiểu. Hiểu một lời giải và tạo ra được một lời giải là hai kỹ năng khác nhau, cách nhau chín tháng, và chỉ một trong hai là thứ mà phỏng vấn hay deadline thực tế kiểm tra.

Thứ có tác dụng thì nhỏ hơn và kém hào nhoáng hơn: học một pattern, luyện nó trên năm tới mười bài cho tới khi pattern thành phản xạ, rồi đi tiếp và quay lại sau một tuần. Mười hai pattern, mỗi cái mười bài, là 120 bài — ít hơn số bài phần lớn mọi người cày — nhưng cho kết quả tốt hơn hẳn, vì sau đó bạn nhận ra hình dạng của bài toán thay vì cố nhớ xem mình đã gặp đúng bài này chưa.

Bài này nói về luyện ở đâu, luyện thế nào, theo thứ tự nào, và cách biến việc luyện tập đó thành một buổi phỏng vấn đạt. Phần nội dung kỹ thuật mà nó dựa vào nằm ở các topic pattern: quy hoạch động, hai con trỏ & cửa sổ trượt, và độ phức tạp thuật toán — cái cuối cùng là thứ bạn sẽ bị hỏi trong mọi buổi phỏng vấn, bất kể đề bài là gì.

Kiến thức nền tảng

Các nền tảng, và mỗi cái thực sự dùng để làm gì

Các platform không thay thế được cho nhau. Mỗi cái tối ưu cho một mục tiêu khác nhau, và chọn sai cái cho mục tiêu của bạn sẽ phí hàng tháng trời.

PlatformPhù hợp nhất choĐịnh dạngGhi chú
LeetCodePhỏng vấn software engineeringBài lẻ, gắn tag theo công ty và chủ đềLựa chọn mặc định, và đúng là như vậy. Chất lượng editorial không đều; tab discussion thường tốt hơn
HackerRankTrack có cấu trúc, bài test sàng lọcBài tập + chứng chỉ + contestNhiều công ty dùng nó cho vòng screening tự động, nên đáng để quen với kiểu I/O của nó
CodeforcesCompetitive programming, tốc độ tư duyContest có rating, Div. 1–4Chất lượng ra đề tốt nhất ngành. Hơi quá đà cho phỏng vấn, nhưng tuyệt vời cho năng lực thô
AtCoderĐường tăng độ khó sạch sẽ, chấm tốtContest Beginner/Regular hàng tuầnContest ABC là cái thang được biên soạn tốt nhất để đi từ “biết viết vòng lặp” tới “biết tư duy”. Editorial có tiếng Anh
CodeChefContest dài, lộ trình học có cấu trúcContest + ladder luyện tậpĐịnh dạng Long Challenge thưởng cho việc tra cứu và kiên trì hơn là tốc độ
EdabitNgười mới hoàn toàn, làm quen cú phápBài tập rất nhỏ, kiểu game hóaKhông phải luyện thuật toán. Đây là công cụ đúng cho giai đoạn “còn vật lộn với cú pháp” trong nền tảng lập trình
ExercismThành thạo ngôn ngữ + review code bởi người thậtBài tập theo từng ngôn ngữ, có mentor phản hồiPhần mentorship mới là điểm chính. Hợp với “tôi muốn viết Go idiomatic”, không hợp với “tôi muốn qua phỏng vấn”
CodewarsXây thói quen, làm đều mỗi ngàyKata xếp hạng theo kyu, có lời giải cộng đồngSo lời giải của mình với các bản được vote cao sau khi giải xong thực sự rất bổ ích
Project EulerGiải toán mang tính toán họcBài đậm chất number theory, không giới hạn thời gianKhông phải luyện phỏng vấn. Tuyệt vời cho nửa “toán” của tư duy thuật toán
InterviewBitLộ trình luyện phỏng vấn có dẫn dắtChương trình sắp theo chủ đề, có giới hạn thời gianGiá trị nằm ở thứ tự chương trình — đã có người quyết định hộ bạn học gì lúc nào
CSES Problem SetPhủ thuật toán một cách hệ thống300 bài chia theo chủ đề, không có editorialDanh sách có cấu trúc miễn phí tốt nhất hiện có. Giải hết mục “Dynamic Programming” và “Graph Algorithms” là bạn thực sự biết DP và graph
Advent of CodeGiải đố vui, thiên về thực dụng25 ngày tháng Mười Hai, mỗi ngày hai phầnLà câu đố chứ không phải câu hỏi phỏng vấn — parsing, mô phỏng, lưới. Rất hợp để giữ thói quen sống sót qua tháng Mười Hai

Nếu chỉ muốn một gợi ý duy nhất: LeetCode để luyện phỏng vấn, CSES để xây chiều sâu thuật toán thật, Codeforces hoặc AtCoder nếu bạn thấy mình thích thứ này và muốn giỏi thật sự. Mọi thứ khác là tùy chọn.

Một ghi chú về các danh sách được biên soạn kiểu “Blind 75” / “NeetCode 150” / “Grind 75”: chúng rất tốt và bạn nên dùng một cái. Giá trị của chúng không nằm ở đề bài (chỉ là các bài LeetCode) mà ở sự biên soạn — có người đủ trình đã loại bỏ phần trùng lặp và phần nhiễu, nên 75 bài phủ đúng không gian pattern mà 400 bài ngẫu nhiên mới phủ được. Hãy chọn một danh sách và làm hết; đừng đi sưu tầm danh sách.

Vòng lặp luyện tập

Đây là vòng lặp thực sự xây dựng kỹ năng, áp dụng cho mỗi bài:

  1. Đọc đề hai lần. Phát biểu lại bằng lời của bạn. Ghi lại ràng buộc input — đó là gợi ý mạnh nhất về độ phức tạp mong muốn (xem phần nhận diện trong quy hoạch động).
  2. Bấm giờ. 25 phút cho easy/medium, 40 phút cho hard. Trong 5–10 phút đầu, chỉ nghĩ, không viết code.
  3. Giải được, hoặc thất bại một cách sạch sẽ. “Thất bại sạch sẽ” nghĩa là: khi hết giờ, hãy viết ra bạn đã thử gì và tắc ở đâu, trong một câu, trước khi mở bất cứ thứ gì.
  4. Đọc editorial — cho tử tế. Không phải “lướt tới lúc thấy thông”. Đọc tới khi bạn giải thích được insight then chốt mà không cần nhìn. Insight then chốt thường chỉ là một câu (“sort theo thời điểm kết thúc”, “state là prefix của mỗi chuỗi”, “dịch đường thấp hơn”). Viết câu đó ra.
  5. Đóng hết mọi thứ và tự viết lại từ đầu. Bước này không phải tùy chọn, và nó chính là bước ai cũng bỏ qua. Đọc lời giải tạo ra ảo giác thành thạo; tái tạo lại nó từ một câu insight mới tạo ra sự thành thạo.
  6. Ghi log. Tên bài, pattern, câu insight, và kết quả ra sao. Một spreadsheet hay một file text thuần là đủ.
  7. Một tuần sau, giải lại từ đầu, chỉ dựa vào dòng log. Nếu không giải được thì bạn chưa học được — bạn chỉ nhận ra nó thôi. Đọc lại và xếp lịch lại.

Bước 7 chính là spaced repetition, và đó là thói quen có đòn bẩy cao nhất trong cả bài này. Lịch chạy tốt: 1 ngày, 1 tuần, 1 tháng. Ba lần lặp với khoảng cách giãn dần biến một lời giải từ “tôi từng thấy cái này” thành thứ bạn nhớ lại được dưới áp lực. Anki hợp với việc này nếu bạn đã dùng nó; mặt trước của card là tên bài kèm ràng buộc, mặt sau là câu insight của bạn.

Timebox, và vì sao việc vật lộn cũng có giới hạn

Đồng hồ 25 phút là sự thỏa hiệp giữa hai kiểu thất bại. Bỏ cuộc sau năm phút thì bạn không bao giờ phát triển được khả năng ngồi lì với một bài chưa giải được — vốn chính là khả năng mà phỏng vấn kiểm tra. Nhất định không mở editorial trong ba tiếng thì bạn đốt cả buổi tối để học một thứ thay vì năm thứ.

Quy tắc đúng: hãy vật lộn một cách hiệu quả cho tới khi bạn ngừng sinh ra ý tưởng mới, rồi dừng. Nếu bạn đã mất mười phút quay vòng qua đúng ba hướng đã thất bại, bạn không đang học, bạn đang ngâm. Hãy tra, rút lấy insight, rồi viết lại — chỗ viết lại mới là chỗ học được.

Một bước trung gian hữu ích trước khi đọc editorial đầy đủ: chỉ đọc tag, hoặc chỉ đọc đoạn đầu tiên của editorial. “Đây là bài sliding window” thường đã là toàn bộ chìa khóa bạn cần, và bạn vẫn giữ được phần lớn giá trị của việc tự giải.

Khái niệm chính

Thứ tự đề xuất đi qua section này

Thứ tự quan trọng hơn phần lớn mọi người nghĩ, vì khoảng một nửa số topic ở đây là điều kiện tiên quyết cho nửa còn lại. Đâm đầu vào graph trước khi thoải mái với queue và đệ quy nghĩa là học ba thứ cùng lúc và chẳng thứ nào ra hồn.

Giai đoạn 1 — Nền tảng (không bỏ qua, cũng đừng nấn ná).

  1. Nền tảng lập trình & pseudocode — chỉ khi bạn chưa thành thạo ngôn ngữ của mình. Edabit hoặc Exercism là công cụ đúng ở đây.
  2. Cấu trúc dữ liệu là gìđộ phức tạp thuật toán. Complexity là từ vựng của mọi cuộc thảo luận về sau và của mọi buổi phỏng vấn. Hãy học nó cho tử tế ngay bây giờ.
  3. Array, linked list, stack & queue, hash table. Khoảng 80% bài phỏng vấn được giải bằng một array, một hash map, hoặc cả hai.

Giai đoạn 2 — Bộ công cụ thuật toán cốt lõi.

  1. Sắp xếptìm kiếm. Binary search xứng đáng nhiều thời gian hơn mức nó thường được dành — đặc biệt là “binary search trên đáp án”, kỹ thuật hiệu suất cao mà ít người luyện nhất trong danh sách này.
  2. Hai con trỏ & cửa sổ trượt. Đúng vậy, không theo thứ tự số — nó chỉ phụ thuộc vào array, xuất hiện liên tục, và là chiến thắng tự tin đến nhanh nhất. Hãy làm nó ở đây.
  3. Đệ quy & chia để trị. Mọi thứ sau đây đều giả định bạn đã thoải mái với đệ quy.

Giai đoạn 3 — Cây và đồ thị.

  1. Cấu trúc dữ liệu cây — traversal, BST. Rồi tới heap & priority queue, thứ mở khóa nhóm bài top-k và merge-k.
  2. Cấu trúc dữ liệu đồ thị — BFS, DFS, connected component, topological sort. Đây là nơi cư trú của một phần lớn các bài “medium/hard”.
  3. Đường đi ngắn nhất, cây khung nhỏ nhất, union-find.

Giai đoạn 4 — Các kỹ thuật giải quyết bài toán.

  1. Brute force, greedy & thuật toán ngẫu nhiên, rồi backtracking.
  2. Quy hoạch động. Để cuối cùng, một cách có chủ đích: nó khó học nhất và xây trực tiếp trên đệ quy cùng memoization. Lao vào DP đầu tiên là lý do phổ biến nhất khiến người ta kết luận rằng mình “dốt thuật toán”.

Giai đoạn 5 — Chiều sâu, nếu bạn muốn.

  1. Cây cân bằng & cây nhiều nhánh, cấu trúc cây nâng cao (trie, segment tree, Fenwick), indexing. Trie xuất hiện trong phỏng vấn khá thường xuyên; segment tree thì gần như không bao giờ, nhưng lại rất phổ biến trong competitive programming.

Riêng cho việc luyện phỏng vấn, Giai đoạn 1–4 chính là chương trình học. Giai đoạn 5 dành cho chiều sâu và cho competitive programming.

Danh sách pattern

Lý do nên tổ chức việc luyện tập theo pattern thay vì theo chủ đề là vì pattern mới là thứ bạn thực sự nhận ra khi bị áp lực thời gian. Đây là danh sách đáng thuộc nằm lòng — mười hai tới mười lăm pattern phủ áp đảo phần lớn các bài phỏng vấn:

PatternDấu hiệu kích hoạtĐược trình bày ở
Hashing để tra cứu O(1)“Đã gặp cái này chưa”, phần bù, đếm./07-hash-tables.md
Two pointers (ngược chiều)Mảng đã sorted, tìm cặp, palindrome./23-two-pointers-and-sliding-window.md
Sliding windowSubarray/chuỗi con liên tiếp kèm ràng buộc./23-two-pointers-and-sliding-window.md
Fast & slow pointersCycle trong linked list, phần tử giữa, thứ n từ cuối./23-two-pointers-and-sliding-window.md
Prefix sumsTổng hợp trên đoạn, tổng subarray có số âm./23-two-pointers-and-sliding-window.md
Binary search (kể cả trên đáp án)Input đã sorted, hoặc một predicate đơn điệu trên một khoảng./09-search-algorithms.md
Merge intervals / sweep lineCác đoạn chồng lấn, lập lịch, đỉnh đồng thời./23-two-pointers-and-sliding-window.md
Heap / top-k / two heaps”k lớn nhất”, “trung vị của một stream”, gộp k list./12-heaps-and-priority-queues.md
Monotonic stack”Phần tử lớn kế tiếp”, histogram, span./06-stacks-and-queues.md
Tree DFS / BFSMọi thứ trên cây; duyệt theo mức; tổng đường đi./10-tree-data-structures.md
Duyệt đồ thị + topological sortLưới, đảo, phụ thuộc, phát hiện cycle./13-graph-data-structures.md
Union-findTính liên thông, gom nhóm, Kruskal./16-disjoint-set-union-find.md
Backtracking”Sinh ra tất cả”, tập con, hoán vị, sudoku./21-backtracking.md
Dynamic programmingĐếm/max/min trên các lựa chọn, greedy sai có chứng minh./22-dynamic-programming.md
Greedy + lập luận trao đổiLựa chọn cục bộ tối ưu có chứng minh (nhớ chứng minh!)./20-brute-force-greedy-and-randomised-algorithms.md

Hãy luyện từng dòng một. Năm tới mười bài trên cùng một pattern, làm liên tiếp, dạy bạn hình dạng của pattern đó — các biến thể, các edge case, và thời điểm nó thôi áp dụng được. Mười bài ngẫu nhiên rải trên mười pattern chỉ dạy bạn mười sự kiện rời rạc.

Giao tiếp trong buổi phỏng vấn kỹ thuật

Phỏng vấn không phải bài kiểm tra giải toán. Nó là một mô phỏng việc làm việc cùng bạn, và code là sản phẩm phụ chứ không phải trọng tâm. Ứng viên giải bài đúng nhưng im lặng thường bị chấm thấp hơn ứng viên giải bài có tương tác và cần một gợi ý. Quy trình dưới đây là thứ người phỏng vấn được huấn luyện để tìm kiếm.

1. Làm rõ trước khi viết code (2–3 phút). Hỏi về kích thước và khoảng giá trị của input, input rỗng và một phần tử, giá trị trùng lặp, số âm, input đã sorted chưa, có được sửa tại chỗ không, trả về gì khi không có đáp án, và input có vừa bộ nhớ không. Phát biểu lại đề bằng lời của bạn và xác nhận.

Đây không phải nghi thức. Đề phỏng vấn cố tình thiếu thông tin, và hỏi chính là cách bạn phát hiện ra rằng mảng đã sorted (mở khóa two pointers), rằng giá trị nằm trong 1..n (mở khóa cyclic sort), hoặc rằng n ≤ 20 (mở khóa bitmask DP). Các ràng buộc là một nửa lời giải.

2. Chạy tay một ví dụ. Lấy một input nhỏ và tự tạo ra output đúng bằng tay. Việc này bắt lỗi hiểu sai ngay lập tức và thường hé lộ cấu trúc của lời giải. Nó cũng cho bạn một test case để dùng về sau.

3. Nêu brute force kèm độ phức tạp, rồi nói rằng bạn có thể làm tốt hơn. Kiểu như: “Cách hiển nhiên là kiểm tra mọi cặp, tốn O(n²) thời gian và O(1) bộ nhớ. Để em xem có làm tốt hơn được không.” Đây là nước đi trội tuyệt đối. Nó cho thấy bạn hiểu đề, đặt sẵn một baseline chạy được lên bàn phòng khi hết giờ, và xác lập mốc độ phức tạp mà bạn đang muốn vượt qua. Đừng bao giờ ngồi im săn lời giải tối ưu — một brute force được nói ra có giá hơn một ý tưởng hay hơn nhưng không nói ra.

4. Nghĩ thành tiếng trong lúc tối ưu. Nói ra bạn đang cân nhắc gì và vì sao bạn loại nó: “Em có thể sort, cho O(n log n), nhưng đề nói chỉ số gốc có ý nghĩa nên em sẽ phải giữ lại chúng — để em thử hash map xem sao.” Những hướng bị loại kèm lý do là bằng chứng của khả năng phán đoán, vốn chính xác là thứ đang được đánh giá. Sự im lặng thì không đọc được và bị chấm là đang bí.

5. Chốt hướng tiếp cận trước khi viết code. “Vậy: hash map từ giá trị sang chỉ số, một lượt duyệt, O(n) thời gian và O(n) bộ nhớ. Em code luôn nhé?” Nếu người phỏng vấn định lái bạn sang hướng khác thì đây là lúc họ làm — và nó cứu bạn khỏi mười lăm phút viết nhầm thứ.

6. Viết code sạch và tường thuật. Tên biến thật, không phải a/b/tmp. Xử lý những edge case bạn đã nhận diện ở bước 1. Nói ra bạn đang làm gì trong lúc làm, nhưng đừng tường thuật cú pháp — hãy tường thuật ý định (“giờ em co cửa sổ lại cho tới khi nó hợp lệ trở lại”).

7. Tự test trước khi bị yêu cầu. Chạy tay code của chính bạn với ví dụ nhỏ ở bước 2, nói thành tiếng, từng dòng, theo dõi các biến. Rồi chạy các edge case: rỗng, một phần tử, toàn phần tử giống nhau, target ở biên. Tự tìm ra bug của mình là tín hiệu tích cực — nó cho thấy đúng thói quen tự kiểm tra mà bạn sẽ áp dụng khi đi làm. Bị người khác chỉ ra bug là tín hiệu trung tính tới tiêu cực.

8. Nêu độ phức tạp cuối cùng và các đánh đổi. O(n) thời gian, O(n) bộ nhớ. Nếu bộ nhớ eo hẹp thì em sẽ sort trước rồi dùng two pointers — O(n log n) thời gian nhưng chỉ O(1) bộ nhớ phụ.” Gọi tên phương án bạn đã không chọn, kèm lý do, là tín hiệu cấp senior và chỉ tốn mười lăm giây.

Những kiểu thất bại thường gặp

Đây là những cách mà người đã chuẩn bị vẫn trượt, xếp đại khái theo tần suất.

Tuần cuối trước buổi phỏng vấn

Tuần cuối không phải để học kiến thức mới. Thứ gì bạn chưa học được tới giờ thì trong bảy ngày cũng sẽ không đáng tin, và việc nhồi nhét chiếm chỗ của phần luyện truy hồi vốn mới thực sự giúp ích.

Còn 7 ngày. Dừng mọi chủ đề mới. Giải lại 20–30 bài bạn đã làm, mỗi pattern một hai bài, dựa vào log của bạn. Tốc độ quan trọng ở đây — bạn đang xây lại khả năng nhớ lại, không phải xây lại sự hiểu.

Còn 5 ngày. Làm hai buổi phỏng vấn thử đầy đủ với người thật, nói thành tiếng, bấm giờ, trên một trình soạn thảo chia sẻ không có autocomplete. Đây là hoạt động giá trị nhất của cả tuần và cũng là thứ người ta né vì nó khó chịu. Chính sự khó chịu đó mới là điểm.

Còn 3 ngày. Rà lại log và liệt kê những pattern bạn vẫn còn ngập ngừng. Làm ba bốn bài cho mỗi cái. Đọc lại câu insight cho mọi thứ còn lại.

Còn 2 ngày. Tìm hiểu về công ty: vòng nào là vòng gì, kéo dài bao lâu, được dùng ngôn ngữ nào, làm trên doc chia sẻ hay IDE thật. Chuẩn bị câu hỏi của bạn dành cho họ, và hai ba câu chuyện dự án cho phần behavioural.

Còn 1 ngày. Một hai bài easy để giữ nhiệt — không bài khó, không bài mới. Đọc lại ghi chú ba mươi phút, không phải ba tiếng. Rồi dừng, và ngủ cho tử tế. Giấc ngủ giúp hiệu suất giải bài ngày hôm sau nhiều hơn bất kỳ lượng ôn tập phút chót nào, và mức chênh không hề nhỏ.

Đến ngày. Khởi động bằng một bài easy trước đó một tiếng, để dòng code đầu tiên bạn viết không phải là trong buổi phỏng vấn. Kiểm tra thiết bị: camera, micro, trình soạn thảo, một cốc nước, và giấy bút để vẽ. Chuẩn bị sẵn các câu hỏi làm rõ dưới dạng checklist — dưới áp lực bạn sẽ quên hỏi, mà hỏi thì đáng giá hơn bất cứ dòng code đơn lẻ nào bạn sắp viết.

Best Practices

Tài liệu tham khảo

Part of the Data Structures & Algorithms Roadmap knowledge base.

Overview

Everything in the previous twenty-three topics is knowledge you can acquire by reading. This one is not. Data structures and algorithms are a skill, and skills are acquired by doing the thing badly, getting feedback, and doing it again — not by reading about people who do it well.

The mistake almost everyone makes is treating practice as a volume problem: “I’ll do 300 problems.” Volume without structure produces people who have seen 300 problems and can solve about 40 of them, because they solved the other 260 by reading the editorial after twenty minutes and feeling like they understood it. Understanding a solution and being able to produce one are different skills with a nine-month gap between them, and only one of them is what an interview or a real deadline tests.

What works is smaller and less glamorous: learn one pattern, drill it on five to ten problems until the pattern is automatic, then move on and come back a week later. Twelve patterns at ten problems each is 120 problems, which is fewer than most people grind, and it produces a far better result — because after it you recognize the shape of a problem instead of trying to remember whether you have seen this exact one before.

This note covers where to practice, how to practice, in what order, and how to convert that practice into a passed interview. The technical content it draws on lives in the pattern notes: dynamic programming, two pointers and sliding window, and algorithmic complexity, which is the one you will be asked to talk about in every single interview regardless of the problem.

Fundamentals

The platforms, and what each is actually for

Platforms are not interchangeable. Each one optimizes for something different, and using the wrong one for your goal wastes months.

PlatformBest forFormatNotes
LeetCodeSoftware engineering interviewsIndividual problems, tagged by company and topicThe default, and correctly so. Editorial quality varies; the discussion tab is often better
HackerRankStructured tracks, screening testsProblems + certifications + contestsMany companies use it for automated first-round screens, so it is worth being fluent in its I/O style
CodeforcesCompetitive programming, thinking speedRated contests, Div. 1–4The strongest problem-setting in the industry. Overkill for interviews, excellent for raw ability
AtCoderClean, well-graded difficulty rampWeekly Beginner/Regular contestsABC contests are the best-curated ladder for going from “can loop” to “can think”. Editorials in English
CodeChefLong contests, structured learning pathsContests + practice laddersLong Challenge format rewards research and persistence over speed
EdabitAbsolute beginners, syntax fluencyVery small, gamified exercisesNot algorithm practice. It is the right tool for the “still fighting the syntax” stage in programming fundamentals
ExercismLanguage fluency + human code reviewExercises per language, mentor feedbackThe mentorship is the point. Best for “I want to write idiomatic Go”, not “I want to pass an interview”
CodewarsHabit-building, small daily repsKata ranked by kyu, community solutionsComparing your solution to the community’s top-voted ones after solving is genuinely instructive
Project EulerMathematical problem solvingNumber-theory-flavoured problems, no time limitsNot interview prep. Excellent for the maths half of algorithmic thinking
InterviewBitGuided interview prep pathTopic-ordered curriculum with time limitsThe curriculum ordering is its value — someone already decided what to study when
CSES Problem SetSystematic algorithm coverage300 problems by topic, no editorialsThe best free structured list in existence. If you solve all of “Dynamic Programming” and “Graph Algorithms”, you know DP and graphs
Advent of CodeFun, practical problem solving25 December days, two parts eachPuzzles, not interview questions — parsing, simulation, and grids. Great for keeping the habit alive in December

If you want a single recommendation: LeetCode for interview preparation, CSES for building actual algorithmic depth, Codeforces or AtCoder if you find you enjoy this and want to get genuinely good. Everything else is optional.

A note on the “Blind 75” / “NeetCode 150” / “Grind 75” curated lists: they are excellent and you should use one. Their value is not the problems (which are just LeetCode problems) but the curation — someone competent removed the redundancy and the noise, so 75 problems cover the same pattern space that 400 random ones would. Pick one list and finish it; do not collect lists.

The practice loop

Here is the loop that actually builds skill, per problem:

  1. Read the problem twice. Restate it in your own words. Write down the input constraints — they are the single strongest hint about the intended complexity (see the recognition heuristics in dynamic programming).
  2. Set a timer. 25 minutes for easy/medium, 40 for hard. Think without writing code for the first 5–10 of them.
  3. Solve it, or fail cleanly. “Fail cleanly” means: when the timer expires, write down what you tried and where you got stuck, in one sentence, before opening anything.
  4. Read the editorial — properly. Not “skim until it clicks”. Read until you can explain the key insight without looking. The key insight is usually one sentence (“sort by end time”, “the state is the prefix of each string”, “move the shorter line”). Write that sentence down.
  5. Close everything and implement it from scratch. This step is not optional and it is the step everyone skips. Reading a solution creates the illusion of competence; reproducing it from the one-sentence insight is what creates the competence.
  6. Log it. Problem name, pattern, the one-sentence insight, and how it went. A spreadsheet or a plain text file is fine.
  7. Re-solve it from scratch a week later, from the log entry alone. If you cannot, you did not learn it — you recognized it. Re-read and re-schedule.

Step 7 is spaced repetition, and it is the single highest-leverage habit in this whole note. The schedule that works: 1 day, 1 week, 1 month. Three repetitions at expanding intervals converts a solution from “I saw that once” into recall you can rely on under pressure. Anki works well for this if you already use it; the card front is the problem name plus constraints, the back is your one-sentence insight.

Timeboxing, and why struggling has a limit

The 25-minute timer is a compromise between two failure modes. Give up after five minutes and you never develop the ability to sit with an unsolved problem, which is precisely the ability an interview tests. Refuse to look at the editorial for three hours and you spend a whole evening learning one thing instead of five.

The right rule: struggle productively until you stop generating new ideas, then stop. If you have spent ten minutes cycling through the same three failed approaches, you are not learning, you are marinating. Look it up, extract the insight, and reimplement — the reimplementation is where the learning is.

A useful middle step before the full editorial: read only the tags or only the first paragraph of the editorial. “This is a sliding window problem” is often all the unlock you need, and you keep most of the value of solving it yourself.

Key Concepts

A suggested order through this section

Order matters more than most people think, because roughly half of these topics are prerequisites for the other half. Attempting graphs before you are comfortable with queues and recursion means learning three things at once and none of them well.

Phase 1 — Foundations (do not skip, do not linger).

  1. Programming fundamentals & pseudocode — only if you are not yet fluent in your language. Edabit or Exercism are the right tools here.
  2. What are data structures and algorithmic complexity. Complexity is the vocabulary of every later discussion and every interview. Learn it properly now.
  3. Arrays, linked lists, stacks and queues, hash tables. About 80% of interview problems are solved with an array, a hash map, or both.

Phase 2 — The core algorithmic toolkit.

  1. Sorting and searching. Binary search deserves more time than it gets — especially “binary search on the answer”, which is the most under-practised high-yield technique on this list.
  2. Two pointers and sliding window. Yes, out of numerical order — it depends only on arrays, it appears constantly, and it is the fastest confidence win available. Do it here.
  3. Recursion and divide and conquer. Everything after this assumes you are comfortable with recursion.

Phase 3 — Trees and graphs.

  1. Tree data structures — traversals, BSTs. Then heaps and priority queues, which unlock the top-k and merge-k families.
  2. Graph data structures — BFS, DFS, connected components, topological sort. This is where a large share of “medium/hard” problems live.
  3. Shortest paths, minimum spanning trees, union-find.

Phase 4 — Problem-solving techniques.

  1. Brute force, greedy, and randomised algorithms, then backtracking.
  2. Dynamic programming. Last, deliberately: it is the hardest to learn and it builds directly on recursion and memoization. Attempting DP first is the most common reason people conclude they are “bad at algorithms”.

Phase 5 — Depth, if you want it.

  1. Balanced and multiway trees, advanced tree structures (trie, segment tree, Fenwick), indexing. Tries appear in interviews reasonably often; segment trees almost never, but they are common in competitive programming.

For interview prep specifically, Phases 1–4 are the syllabus. Phase 5 is for depth and for competitive programming.

The pattern list

The reason to organize practice by pattern rather than by topic is that patterns are what you actually recognize under time pressure. This is the list worth internalizing — twelve to fifteen patterns cover the overwhelming majority of interview problems:

PatternTriggerWhere it is covered
Hashing for O(1) lookup”Have I seen this before”, complements, counting./07-hash-tables.md
Two pointers (opposite)Sorted array, pairs, palindromes./23-two-pointers-and-sliding-window.md
Sliding windowContiguous subarray/substring with a constraint./23-two-pointers-and-sliding-window.md
Fast & slow pointersLinked list cycles, middle, n-th from end./23-two-pointers-and-sliding-window.md
Prefix sumsRange aggregates, subarray sums with negatives./23-two-pointers-and-sliding-window.md
Binary search (incl. on the answer)Sorted input, or a monotone predicate over a range./09-search-algorithms.md
Merge intervals / sweep lineOverlapping ranges, scheduling, concurrency peaks./23-two-pointers-and-sliding-window.md
Heap / top-k / two heaps”k largest”, “median of a stream”, merge k lists./12-heaps-and-priority-queues.md
Monotonic stack”Next greater element”, histogram, spans./06-stacks-and-queues.md
Tree DFS / BFSAnything on a tree; level-order; path sums./10-tree-data-structures.md
Graph traversal + topological sortGrids, islands, dependencies, cycle detection./13-graph-data-structures.md
Union-findConnectivity, grouping, Kruskal./16-disjoint-set-union-find.md
Backtracking”Generate all”, subsets, permutations, sudoku./21-backtracking.md
Dynamic programmingCount/max/min over choices, greedy provably fails./22-dynamic-programming.md
Greedy + exchange argumentLocal choice provably optimal (prove it!)./20-brute-force-greedy-and-randomised-algorithms.md

Drill one row at a time. Five to ten problems on a single pattern, done consecutively, teaches you the pattern’s shape — the variations, the edge cases, the moment it stops applying. Ten random problems across ten patterns teaches you ten disconnected facts.

Communicating in a technical interview

An interview is not a problem-solving test. It is a simulation of working with you, and the code is the artifact, not the point. Candidates who solve the problem silently and correctly are routinely rated below candidates who solve it collaboratively with a hint. The protocol below is what interviewers are trained to look for.

1. Clarify before you code (2–3 minutes). Ask about input size and ranges, empty and single-element inputs, duplicates, negative numbers, whether the input is sorted, whether it can be modified in place, what to return when there is no answer, and whether the input fits in memory. Restate the problem in your own words and confirm.

This is not a ritual. Interview problems are deliberately underspecified, and asking is how you find out that the array is sorted (which unlocks two pointers), or that values are in 1..n (which unlocks cyclic sort), or that n ≤ 20 (which unlocks bitmask DP). The constraints are half the solution.

2. Work an example by hand. Take a small input and produce the correct output manually. This catches misunderstandings immediately and often reveals the structure of the solution. It also gives you a test case for later.

3. State the brute force, with its complexity, and then say you can do better. Something like: “The obvious approach is to check every pair, which is O(n²) time and O(1) space. Let me see if I can do better.” This is a strictly dominant move. It shows you understand the problem, it puts a working baseline on the table in case you run out of time, and it establishes the complexity you are trying to beat. Never sit in silence hunting for the optimal solution — a stated brute force is worth more than an unstated better idea.

4. Think out loud while you optimize. Say what you are considering and why you are rejecting it: “I could sort, which gives O(n log n), but the problem says the original indices matter, so I’d need to keep them — let me try a hash map instead.” Rejected approaches with reasons are evidence of judgement, which is exactly what is being assessed. Silence is unreadable and gets scored as being stuck.

5. Agree on the approach before writing code. “So: hash map from value to index, one pass, O(n) time and O(n) space. Shall I code that?” If the interviewer is going to redirect you, this is when they will — and it saves you fifteen minutes of writing the wrong thing.

6. Write clean code and narrate. Real names, not a/b/tmp. Handle the edge cases you identified in step 1. Say what you are doing as you do it, but do not narrate syntax — narrate intent (“now I’m shrinking the window until it’s valid again”).

7. Test it yourself, before being asked. Trace through your own code with the small example from step 2, out loud, line by line, watching the variables. Then run the edge cases: empty, one element, all-identical, the target at the boundary. Finding your own bug is a positive signal — it demonstrates exactly the self-checking you would apply on the job. Being told about your bug is a neutral-to-negative one.

8. State the final complexity and any trade-offs. O(n) time, O(n) space. If memory were tight I’d sort first and use two pointers — O(n log n) time but O(1) extra space.” Naming the alternative you did not take, and why, is a senior-level signal that costs you fifteen seconds.

Common failure modes

These are the ways prepared people still fail, roughly ordered by how often they happen.

The last week before an interview

The week before is not for learning new material. Anything you have not learned by now will not be reliable in seven days, and cramming displaces the retrieval practice that would actually help.

7 days out. Stop new topics. Re-solve 20–30 problems you have already done, one or two from each pattern, from your log. Speed matters here — you are rebuilding recall, not understanding.

5 days out. Do two full mock interviews with a real human, out loud, timed, on a shared editor with no autocomplete. This is the single highest-value activity of the whole week and the one people avoid because it is uncomfortable. That discomfort is the point.

3 days out. Go through your log and list the patterns where you still hesitate. Do three or four problems on each. Reread your one-sentence insights for everything else.

2 days out. Research the company: which round is which, how long, what language you may use, whether it is a shared doc or a real IDE. Prepare your questions for them, and your two or three project stories for the behavioural section.

1 day out. One or two easy problems to stay warm — nothing hard, nothing new. Reread your notes for thirty minutes, not three hours. Then stop, and sleep properly. Sleep does more for problem-solving performance the next day than any amount of last-minute revision, and the effect is not small.

On the day. Warm up with one easy problem an hour before, so the first code you write is not in the interview. Check your setup: camera, microphone, editor, a glass of water, and a pen and paper for diagrams. Have your clarifying questions ready as a checklist — under stress you will forget to ask, and asking is worth more than any single line of code you will write.

Best Practices

References