Bỏ qua để đến nội dung

Bài tập lập trình - Nâng cao

Trang này tổng hợp 100 bài tập lập trình nâng cao, dành cho bạn nào đã làm quen với các kiến thức cơ bản ở trang Bài tập lập trình - Cơ bản. Nội dung xoay quanh thuật toán sắp xếp/tìm kiếm, đệ quy & backtracking, quy hoạch động, cấu trúc dữ liệu, lập trình hướng đối tượng, lập trình hàm và các thư viện chuẩn hữu ích của từng ngôn ngữ. Mỗi bài có đáp án bằng nhiều ngôn ngữ lập trình khác nhau để bạn tiện đối chiếu.

Mỗi bài đều có phần đáp án gợi ý ở dưới, mặc định ẩn đi - bạn nên tự làm trước, sau đó bấm vào “Xem đáp án” để đối chiếu. Đáp án chỉ là một cách giải, không phải cách duy nhất và không phải lúc nào cũng tối ưu nhất.


1. Selection Sort

Cài đặt thuật toán sắp xếp chọn (selection sort) để sắp xếp tăng dần một list số.

Ví dụ:

Input: [64, 25, 12, 22, 11]
Output: [11, 12, 22, 25, 64]
Xem đáp án
def selection_sort(arr):
n = len(arr)
for i in range(n):
# Tìm vị trí phần tử nhỏ nhất trong phần chưa sắp xếp
min_idx = i
for j in range(i + 1, n):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
return arr
print(selection_sort([64, 25, 12, 22, 11]))

2. Insertion Sort

Cài đặt thuật toán sắp xếp chèn (insertion sort) để sắp xếp tăng dần một list số.

Ví dụ:

Input: [12, 11, 13, 5, 6]
Output: [5, 6, 11, 12, 13]
Xem đáp án
Đang tải lời giải…

3. Merge Sort

Cài đặt thuật toán sắp xếp trộn (merge sort) theo kiểu chia để trị (divide and conquer).

Ví dụ:

Input: [38, 27, 43, 3, 9, 82, 10]
Output: [3, 9, 10, 27, 38, 43, 82]
Xem đáp án
Đang tải lời giải…

4. Quick Sort

Cài đặt thuật toán sắp xếp nhanh (quick sort) dùng phần tử cuối làm chốt (pivot).

Ví dụ:

Input: [10, 7, 8, 9, 1, 5]
Output: [1, 5, 7, 8, 9, 10]
Xem đáp án
Đang tải lời giải…

5. Counting Sort

Cài đặt thuật toán sắp xếp đếm (counting sort), áp dụng cho list số nguyên không âm.

Ví dụ:

Input: [4, 2, 2, 8, 3, 3, 1]
Output: [1, 2, 2, 3, 3, 4, 8]
Xem đáp án
Đang tải lời giải…

6. Sắp xếp theo nhiều tiêu chí

Cho một list các dictionary học sinh {"ten": ..., "diem": ..., "tuoi": ...}. Sắp xếp giảm dần theo điểm, nếu điểm bằng nhau thì sắp tăng dần theo tuổi.

Xem đáp án
Đang tải lời giải…

7. Tìm kiếm nhị phân (Binary Search)

Cài đặt tìm kiếm nhị phân trên một list đã sắp xếp tăng dần, trả về index hoặc -1 nếu không tìm thấy.

Ví dụ:

Input: arr=[1, 3, 5, 7, 9, 11], target=7
Output: 3
Xem đáp án
Đang tải lời giải…

8. Tìm kiếm nhị phân đệ quy

Viết lại bài toán tìm kiếm nhị phân bằng đệ quy thay vì vòng lặp.

Xem đáp án
Đang tải lời giải…

9. Tìm kiếm trong list đã xoay (Rotated Sorted Array)

Cho một list đã sắp xếp tăng dần rồi bị xoay tại một điểm bất kỳ (ví dụ [4,5,6,7,0,1,2]). Tìm vị trí của target với độ phức tạp O(log n) (nghĩa là mỗi bước loại bỏ được một nửa số phần tử còn lại cần xét, giống tìm kiếm nhị phân, thay vì duyệt qua từng phần tử).

Ví dụ:

Input: arr=[4, 5, 6, 7, 0, 1, 2], target=0
Output: 4
Xem đáp án
Đang tải lời giải…

10. Tìm phần tử xuất hiện lẻ số lần (dùng XOR)

Cho một list mà mọi phần tử đều xuất hiện đúng 2 lần, trừ một phần tử xuất hiện đúng 1 lần. Tìm phần tử đó, dùng phép toán XOR (^), không dùng thêm bộ nhớ phụ.

Ví dụ:

Input: [4, 1, 2, 1, 2]
Output: 4
Xem đáp án
Đang tải lời giải…

Backtracking (quay lui) là kỹ thuật thử từng lựa chọn một cách đệ quy; nếu lựa chọn đó dẫn đến ngõ cụt (không thể tạo ra lời giải hợp lệ), quay lại bước trước và thử lựa chọn khác, cho đến khi tìm ra lời giải hoặc thử hết mọi khả năng. Xem thêm lý thuyết: Đệ quy (Recursion).

11. Tháp Hà Nội (Tower of Hanoi)

Viết hàm đệ quy in ra các bước di chuyển để giải bài toán Tháp Hà Nội với n đĩa.

Ví dụ:

Input: n=2, source=A, destination=C, auxiliary=B
Output:
Di chuyển đĩa 1 từ A sang B
Di chuyển đĩa 2 từ A sang C
Di chuyển đĩa 1 từ B sang C
Xem đáp án
Đang tải lời giải…

12. Tổ hợp chập k (Combinations)

Viết hàm đệ quy combinations(arr, k) sinh ra tất cả tổ hợp chập k phần tử từ list arr (không dùng itertools).

Ví dụ:

Input: arr=[1, 2, 3, 4], k=2
Output: [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]
Xem đáp án
Đang tải lời giải…

13. Hoán vị của list (Permutations)

Viết hàm đệ quy permutations(arr) sinh ra tất cả hoán vị của list arr (không dùng itertools).

Ví dụ:

Input: [1, 2, 3]
Output: [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]
Xem đáp án
Đang tải lời giải…

14. Tập con (Subsets / Power Set)

Viết hàm đệ quy sinh ra tất cả tập con (kể cả tập rỗng) của một list.

Ví dụ:

Input: [1, 2, 3]
Output: [], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]
Xem đáp án
Đang tải lời giải…

15. Bài toán N-Queens

Đếm số cách đặt n quân hậu trên bàn cờ n x n sao cho không có 2 quân nào ăn nhau, dùng backtracking.

Ví dụ:

Input: n=4
Output: 2
Xem đáp án
Đang tải lời giải…

16. Đường đi trong lưới (Grid Paths)

Đếm số đường đi từ góc trên-trái đến góc dưới-phải của một lưới m x n, chỉ được di chuyển sang phải hoặc xuống dưới.

Ví dụ:

Input: m=3, n=3
Output: 6
Xem đáp án
Đang tải lời giải…

17. Subset Sum

Cho một list số nguyên dương và một tổng đích target. Kiểm tra xem có tồn tại một tập con nào của list có tổng bằng target hay không, dùng đệ quy.

Ví dụ:

Input: arr=[3, 34, 4, 12, 5, 2], target=9
Output: True
Xem đáp án
Đang tải lời giải…

18. Số Catalan bằng đệ quy

Số Catalan thứ n được tính bằng công thức đệ quy: C(0) = 1, C(n) = sum(C(i) * C(n-1-i)) với i từ 0 đến n-1. Viết hàm đệ quy tính số Catalan thứ n.

Ví dụ:

Input: n=4
Output: 14
Xem đáp án
Đang tải lời giải…

19. Ghép ngoặc hợp lệ (Generate Parentheses)

Với n cặp ngoặc, sinh ra tất cả các chuỗi ngoặc () hợp lệ có thể tạo được, dùng backtracking.

Ví dụ:

Input: n=3
Output: ['((()))', '(()())', '(())()', '()(())', '()()()']
Xem đáp án
Đang tải lời giải…

20. Chia list thành 2 phần có tổng gần bằng nhau

Dùng đệ quy để tìm cách chia một list số nguyên dương thành 2 phần sao cho hiệu tổng 2 phần là nhỏ nhất có thể.

Ví dụ:

Input: [1, 6, 11, 5]
Output: 1
Xem đáp án
Đang tải lời giải…

Nhóm 4: Quy hoạch động (Dynamic Programming)

Phần tiêu đề “Nhóm 4: Quy hoạch động (Dynamic Programming)”

Quy hoạch động (Dynamic Programming - DP) là kỹ thuật giải bài toán lớn bằng cách chia thành các bài toán con nhỏ hơn có tính chất lặp lại, giải từng bài toán con một lần rồi lưu lại kết quả (thường trong một mảng gọi là dp) để tái sử dụng thay vì tính lại nhiều lần.

21. Fibonacci với Memoization

Tối ưu hàm tính số Fibonacci thứ n bằng kỹ thuật ghi nhớ (memoization) để tránh tính lại nhiều lần.

Ví dụ:

Input: n=50
Output: 12586269025
Xem đáp án
Đang tải lời giải…

22. Fibonacci Bottom-up

Tính số Fibonacci thứ n bằng quy hoạch động kiểu bottom-up (dùng vòng lặp, không đệ quy).

Ví dụ:

Input: n=30
Output: 832040
Xem đáp án
Đang tải lời giải…

23. Bài toán cái túi 0/1 (0/1 Knapsack)

Cho n món đồ, mỗi món có trọng lượng và giá trị, và một túi có sức chứa capacity. Tìm giá trị lớn nhất có thể mang được (mỗi món chỉ lấy 0 hoặc 1 lần).

Ví dụ:

Input: weights=[1, 3, 4, 5], values=[1, 4, 5, 7], capacity=7
Output: 9
Xem đáp án
Đang tải lời giải…

24. Dãy con chung dài nhất (Longest Common Subsequence)

Tìm độ dài dãy con chung dài nhất giữa 2 chuỗi.

Ví dụ:

Input: s1="ABCBDAB", s2="BDCABA"
Output: 4
Xem đáp án
Đang tải lời giải…

25. Khoảng cách chỉnh sửa (Edit Distance)

Tính số phép biến đổi tối thiểu (thêm, xóa, sửa 1 ký tự) để biến chuỗi s1 thành chuỗi s2.

Ví dụ:

Input: s1="kitten", s2="sitting"
Output: 3
Xem đáp án
Đang tải lời giải…

26. Đổi tiền tối ưu (Coin Change)

Cho một list mệnh giá tiền xu và một số tiền amount. Tìm số lượng xu tối thiểu để tạo thành amount (trả về -1 nếu không thể).

Ví dụ:

Input: coins=[1, 2, 5], amount=11
Output: 3
Xem đáp án
Đang tải lời giải…

27. Dãy con tăng dài nhất (Longest Increasing Subsequence)

Tìm độ dài dãy con tăng dần dài nhất trong một list số.

Ví dụ:

Input: [10, 9, 2, 5, 3, 7, 101, 18]
Output: 4
Xem đáp án
Đang tải lời giải…

28. Tổng dãy con lớn nhất (Kadane’s Algorithm)

Tìm tổng lớn nhất của một dãy con liên tiếp trong list số (có thể có số âm).

Ví dụ:

Input: [-2, 1, -3, 4, -1, 2, 1, -5, 4]
Output: 6
Xem đáp án
Đang tải lời giải…

29. Leo cầu thang (Climbing Stairs)

Có n bậc cầu thang, mỗi bước bạn có thể leo 1 hoặc 2 bậc. Đếm số cách khác nhau để leo lên đến bậc thứ n.

Ví dụ:

Input: n=5
Output: 8
Xem đáp án
Đang tải lời giải…

30. Kẻ trộm nhà (House Robber)

Một tên trộm không thể trộm 2 nhà liền kề nhau. Cho list giá trị tiền ở mỗi nhà, tìm số tiền tối đa có thể trộm được.

Ví dụ:

Input: [2, 7, 9, 3, 1]
Output: 12
Xem đáp án
Đang tải lời giải…

31. Stack (Ngăn xếp)

Cài đặt cấu trúc dữ liệu Stack bằng class, hỗ trợ push, pop, peek, is_empty.

Xem đáp án
Đang tải lời giải…

32. Kiểm tra ngoặc hợp lệ (dùng Stack)

Dùng Stack để kiểm tra một chuỗi ngoặc (gồm (), [], {}) có hợp lệ (đóng mở đúng thứ tự) hay không.

Ví dụ:

Input: "({[]})"
Output: True
Input: "([)]"
Output: False
Xem đáp án
Đang tải lời giải…

33. Queue (Hàng đợi) bằng deque

Cài đặt cấu trúc dữ liệu Queue bằng collections.deque, hỗ trợ enqueue, dequeue.

Xem đáp án
Đang tải lời giải…

34. Linked List đơn giản

Cài đặt Linked List (danh sách liên kết đơn) với các thao tác append và print_list.

Xem đáp án
Đang tải lời giải…

35. Đảo ngược Linked List

Viết hàm đảo ngược một Linked List (dùng lại class Node/LinkedList ở bài trước).

Xem đáp án
Đang tải lời giải…

36. Binary Tree - Duyệt cây

Cài đặt cây nhị phân đơn giản và viết 3 hàm duyệt: preorder, inorder, postorder.

Xem đáp án
Đang tải lời giải…

37. Tính chiều cao cây nhị phân

Viết hàm đệ quy tính chiều cao (số tầng) của một cây nhị phân.

Ví dụ: cây 1 có con trái 2 (con trái là 4) và con phải 3.

Output: 3
Xem đáp án
Đang tải lời giải…

38. Kiểm tra cây đối xứng (Symmetric Tree)

Kiểm tra một cây nhị phân có đối xứng qua trục dọc hay không.

Ví dụ: cây gốc 1, con trái 2 (con trái 3, con phải 4), con phải 2 (con trái 4, con phải 3).

Output: True
Xem đáp án
Đang tải lời giải…

39. Duyệt cây theo tầng (Level Order / BFS)

Duyệt cây nhị phân theo từng tầng, in ra danh sách giá trị của mỗi tầng.

Ví dụ: cây gốc 3, con trái 9, con phải 20 (con trái 15, con phải 7).

Output: [[3], [9, 20], [15, 7]]
Xem đáp án
Đang tải lời giải…

40. Binary Search Tree - Thêm và tìm kiếm

Cài đặt cây tìm kiếm nhị phân (BST) với thao tác insert và search.

Ví dụ:

Input: insert [50, 30, 70, 20, 40, 60, 80] rồi search(40)
Output: True
Input: search(100)
Output: False
Xem đáp án
Đang tải lời giải…

Nhóm 6: Lập trình hướng đối tượng (OOP) nâng cao

Phần tiêu đề “Nhóm 6: Lập trình hướng đối tượng (OOP) nâng cao”

Xem thêm lý thuyết: Classes và Objects, Kế thừa (Inheritance), Đa hình (Polymorphism), Đóng gói (Encapsulation), Special Methods (Magic Methods), Constructor và Methods.

41. Kế thừa (Inheritance)

Viết class Animal với phương thức speak(), sau đó viết class Dog và Cat kế thừa từ Animal và ghi đè (override) phương thức speak().

Xem đáp án
Đang tải lời giải…

42. Đa hình (Polymorphism)

Viết một hàm calculate_area(shape) nhận vào các đối tượng hình học khác nhau (Square, Circle) và gọi đúng phương thức area() tương ứng nhờ đa hình.

Xem đáp án
Đang tải lời giải…

43. Encapsulation (property, getter/setter)

Viết class BankAccount với thuộc tính _balance được bảo vệ, dùng @property để đọc và @balance.setter để kiểm tra không cho set số dư âm.

Xem đáp án
Đang tải lời giải…

44. Static Method và Class Method

Viết class MathUtils có 1 @staticmethod tính bình phương và 1 @classmethod tạo đối tượng Point từ chuỗi "x,y".

Xem đáp án
Đang tải lời giải…

45. __str__ và __repr__

Viết class Product với __str__ (hiển thị thân thiện cho người dùng) và __repr__ (hiển thị cho lập trình viên/debug).

Xem đáp án
Đang tải lời giải…

46. Nạp chồng toán tử (Operator Overloading)

Viết class Vector2D biểu diễn vector 2 chiều, nạp chồng toán tử +, - và ==.

Xem đáp án
Đang tải lời giải…

47. Abstract Base Class

Dùng module abc để tạo class trừu tượng Shape với phương thức trừu tượng perimeter(), ép các class con phải cài đặt phương thức này.

Xem đáp án
Đang tải lời giải…

48. Dataclass

Dùng @dataclass để viết class Employee gọn hơn, tự động có __init__, __repr__ và __eq__.

Xem đáp án
Đang tải lời giải…

49. So sánh đối tượng (__eq__, __lt__) để sắp xếp

Viết class Student cài đặt __eq__ và __lt__ để có thể dùng trực tiếp sorted() theo điểm số.

Xem đáp án
Đang tải lời giải…

50. Singleton Pattern

Cài đặt mẫu thiết kế Singleton đơn giản, đảm bảo một class chỉ có duy nhất 1 đối tượng được tạo ra.

Xem đáp án
Đang tải lời giải…

Closure là khi một hàm con “nhớ” được các biến trong hàm cha bao quanh nó, ngay cả sau khi hàm cha đã chạy xong (xem ví dụ ở bài 51). Xem thêm lý thuyết: Decorators (Hàm trang trí), Generators và Iterators, Context Managers (with statement).

51. Closure - Bộ đếm

Viết một closure make_counter() trả về hàm count() mỗi lần gọi sẽ tăng và trả về một biến đếm được “nhớ” bên trong closure.

Xem đáp án
Đang tải lời giải…

52. Decorator đo thời gian chạy hàm

Viết decorator @timer in ra thời gian thực thi của hàm được trang trí.

Xem đáp án
Đang tải lời giải…

53. Decorator ghi log

Viết decorator @log_calls in ra tên hàm cùng tham số truyền vào mỗi khi hàm được gọi.

Xem đáp án
Đang tải lời giải…

54. Decorator tự động thử lại (Retry)

Viết decorator @retry(times) tự động gọi lại hàm tối đa times lần nếu hàm ném ra exception.

Xem đáp án
Đang tải lời giải…

55. Generator sinh dãy Fibonacci

Viết một generator function fibonacci_gen() sinh vô hạn các số Fibonacci, dùng yield.

Xem đáp án
Đang tải lời giải…

56. Generator đọc dữ liệu lớn theo từng dòng

Viết generator read_file_lines(file_path) đọc file lớn từng dòng một, tránh load toàn bộ file vào bộ nhớ.

Xem đáp án
Đang tải lời giải…

57. yield from

Viết generator chain_generators(gen1, gen2) dùng yield from để nối 2 generator lại thành 1 chuỗi giá trị liên tục.

Xem đáp án
Đang tải lời giải…

58. Generator Expression vs List Comprehension

Viết cùng 1 phép tính bình phương các số từ 1 đến 1 triệu bằng cả list comprehension và generator expression, so sánh kích thước bộ nhớ bằng sys.getsizeof.

Xem đáp án
Đang tải lời giải…

59. Decorator cache kết quả (tự viết memoization)

Viết decorator @cache_result tự lưu lại kết quả các lần gọi hàm trước đó, tránh tính toán lại (không dùng functools.lru_cache).

Xem đáp án
Đang tải lời giải…

60. Context Manager tự viết (class)

Viết một class context manager FileOpener (cài đặt __enter__ và __exit__) để dùng với cú pháp with.

Xem đáp án
Đang tải lời giải…

Nhóm 8: Lập trình hàm (Functional Programming)

Phần tiêu đề “Nhóm 8: Lập trình hàm (Functional Programming)”

61. reduce tính tổng và tích

Dùng functools.reduce để tính tổng và tích các phần tử của một list số.

Xem đáp án
Đang tải lời giải…

62. Kết hợp map và filter

Cho một list chuỗi số, dùng filter để loại các chuỗi không phải số, dùng map để chuyển các chuỗi còn lại thành int và nhân đôi giá trị.

Xem đáp án
Đang tải lời giải…

63. functools.partial

Dùng functools.partial để tạo ra một hàm mới từ hàm nhan(a, b) với a đã được cố định sẵn.

Xem đáp án
Đang tải lời giải…

64. itertools.combinations

Dùng itertools.combinations để in ra tất cả tổ hợp chập 2 của một list.

Xem đáp án
Đang tải lời giải…

65. itertools.permutations

Dùng itertools.permutations để in ra tất cả hoán vị của một list 3 phần tử.

Xem đáp án
Đang tải lời giải…

66. itertools.groupby

Cho một list số đã sắp xếp, dùng itertools.groupby để nhóm các số theo tính chẵn/lẻ.

Xem đáp án
Đang tải lời giải…

67. sorted với key phức tạp

Cho một list các tuple (ten, tuoi). Sắp xếp theo độ dài tên tăng dần, nếu bằng nhau thì theo tuổi giảm dần.

Xem đáp án
Đang tải lời giải…

68. any và all nâng cao

Cho một list các list con điểm số, dùng any/all kết hợp generator expression để kiểm tra: (1) có học sinh nào toàn điểm 10 không, (2) tất cả học sinh có ít nhất 1 điểm trên 8 không.

Xem đáp án
Đang tải lời giải…

Xem thêm lý thuyết: Date and Time (datetime module), Regular Expressions, Làm việc với JSON.

69. collections.Counter - Ký tự phổ biến nhất

Dùng Counter để tìm ra 3 ký tự xuất hiện nhiều nhất trong một chuỗi.

Xem đáp án
Đang tải lời giải…

70. collections.defaultdict - Nhóm dữ liệu

Cho một list các tuple (name, subject). Dùng defaultdict để nhóm danh sách môn học theo từng người.

Xem đáp án
Đang tải lời giải…

71. collections.namedtuple

Dùng namedtuple để tạo kiểu dữ liệu Point (có x, y) gọn nhẹ hơn class thông thường.

Xem đáp án
Đang tải lời giải…

72. datetime - Tính số ngày giữa 2 mốc thời gian

Dùng module datetime để tính số ngày giữa 2 ngày cho trước.

Xem đáp án
Đang tải lời giải…

73. re - Kiểm tra định dạng email

Dùng module re (regular expression) để kiểm tra một chuỗi có đúng định dạng email cơ bản hay không, có cho nhập lại nếu sai định dạng.

Xem đáp án
Đang tải lời giải…

74. re - Trích xuất số điện thoại

Dùng re.findall để trích xuất tất cả số điện thoại (dạng 10 chữ số) xuất hiện trong một đoạn văn bản.

Xem đáp án
Đang tải lời giải…

75. json - Đọc và ghi dữ liệu JSON

Dùng module json để lưu một dictionary vào file .json, sau đó đọc lại và in ra.

Xem đáp án
Đang tải lời giải…

76. os / pathlib - Liệt kê file trong thư mục

Dùng pathlib để liệt kê tất cả các file có đuôi .txt trong thư mục hiện tại.

Xem đáp án
Đang tải lời giải…

77. random - Chọn ngẫu nhiên không trùng

Dùng random.sample để chọn ngẫu nhiên 5 số không trùng nhau từ 1 đến 45 (giống quay số trúng thưởng).

Xem đáp án
Đang tải lời giải…

78. statistics - Thống kê cơ bản

Dùng module statistics để tính trung bình cộng, trung vị (median) và độ lệch chuẩn (standard deviation) của một list điểm số.

Xem đáp án
Đang tải lời giải…

Xem thêm lý thuyết: Exception Handling (Try/Except).

79. Phân cấp Exception tùy chỉnh

Tạo một hệ thống exception phân cấp cho việc rút tiền ngân hàng: AccountError (lớp cha), InsufficientBalanceError và InvalidAmountError (kế thừa từ lớp cha).

Xem đáp án
Đang tải lời giải…

80. Chained Exception (raise ... from ...)

Viết chương trình đọc số từ chuỗi, khi gặp lỗi định dạng thì ném ra một exception mới nhưng vẫn giữ lại nguyên nhân gốc bằng raise ... from ....

Xem đáp án
Đang tải lời giải…

81. Context Manager xử lý lỗi (__exit__ trả về True)

Viết context manager SuppressError cho phép bỏ qua một loại exception cụ thể xảy ra bên trong khối with.

Xem đáp án
Đang tải lời giải…

82. finally luôn được thực thi

Viết chương trình minh họa khối finally luôn chạy dù có exception hay không, hay dù có return sớm trong hàm.

Xem đáp án
Đang tải lời giải…

83. Validate dữ liệu nhập với nhiều loại lỗi

Viết hàm input_age() yêu cầu người dùng nhập tuổi, bắt cả lỗi ValueError (không phải số) lẫn lỗi tuổi không hợp lệ (âm hoặc quá lớn), cho nhập lại đến khi hợp lệ.

Xem đáp án
Đang tải lời giải…

Nhóm 11: Thuật toán số học & ma trận nâng cao

Phần tiêu đề “Nhóm 11: Thuật toán số học & ma trận nâng cao”

84. Sàng Eratosthenes

Cài đặt thuật toán Sàng Eratosthenes để tìm tất cả số nguyên tố nhỏ hơn n, hiệu quả hơn nhiều so với kiểm tra từng số.

Ví dụ:

Input: n=20
Output: [2, 3, 5, 7, 11, 13, 17, 19]
Xem đáp án
Đang tải lời giải…

85. Nhân 2 ma trận

Viết hàm nhân 2 ma trận (list 2 chiều) với nhau, không dùng thư viện ngoài.

Ví dụ:

Input: a=[[1,2],[3,4]], b=[[5,6],[7,8]]
Output: [[19, 22], [43, 50]]
Xem đáp án
Đang tải lời giải…

86. Chuyển vị ma trận (Transpose)

Viết hàm chuyển vị một ma trận (đổi hàng thành cột), không dùng thư viện ngoài.

Ví dụ:

Input: [[1, 2, 3], [4, 5, 6]]
Output: [[1, 4], [2, 5], [3, 6]]
Xem đáp án
Đang tải lời giải…

87. Xoay ma trận vuông 90 độ

Viết hàm xoay một ma trận vuông 90 độ theo chiều kim đồng hồ, không dùng bộ nhớ phụ (in-place).

Ví dụ:

Input: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Output: [[7, 4, 1], [8, 5, 2], [9, 6, 3]]
Xem đáp án
Đang tải lời giải…

88. Kiểm tra số chính phương không dùng sqrt

Kiểm tra một số nguyên dương có phải là số chính phương hay không, dùng thuật toán tìm kiếm nhị phân thay vì math.sqrt.

Ví dụ:

Input: 16
Output: True
Input: 18
Output: False
Xem đáp án
Đang tải lời giải…

89. Số nguyên tố Mersenne

Số Mersenne có dạng 2p - 1. Viết chương trình kiểm tra với p là số nguyên tố, số Mersenne tương ứng có phải cũng là số nguyên tố hay không.

Xem đáp án
Đang tải lời giải…

BFS (Breadth-First Search - duyệt theo chiều rộng) thăm hết các đỉnh gần nhất trước, giống lan ra từng vòng tròn đồng tâm. DFS (Depth-First Search - duyệt theo chiều sâu) đi sâu theo một nhánh đến hết mức có thể rồi mới quay lại thử nhánh khác. Đồ thị trong nhóm bài này được biểu diễn bằng adjacency list (danh sách kề): một dictionary mà mỗi key là 1 đỉnh, value là list các đỉnh kề với nó.

90. Duyệt đồ thị theo chiều rộng (BFS)

Cho một đồ thị biểu diễn bằng dictionary (adjacency list), duyệt đồ thị theo chiều rộng (BFS) bắt đầu từ 1 đỉnh.

Ví dụ:

Input: graph={"A":["B","C"],"B":["A","D","E"],"C":["A","F"],"D":["B"],"E":["B","F"],"F":["C","E"]}, start="A"
Output: ['A', 'B', 'C', 'D', 'E', 'F']
Xem đáp án
Đang tải lời giải…

91. Duyệt đồ thị theo chiều sâu (DFS) đệ quy

Với đồ thị ở bài trước, viết hàm duyệt theo chiều sâu (DFS) bằng đệ quy.

Ví dụ:

Input: graph (như bài 90), start="A"
Output: ['A', 'B', 'D', 'E', 'F', 'C']
Xem đáp án
Đang tải lời giải…

92. Kiểm tra đồ thị vô hướng có chu trình

Kiểm tra một đồ thị vô hướng (dạng adjacency list) có tồn tại chu trình (cycle) hay không, dùng DFS.

Ví dụ:

Input: {"A": ["B"], "B": ["A", "C"], "C": ["B", "A"]}
Output: True
Input: {"A": ["B"], "B": ["A", "C"], "C": ["B"]}
Output: False
Xem đáp án
Đang tải lời giải…

93. Đường đi ngắn nhất không trọng số (BFS)

Tìm đường đi ngắn nhất (số bước ít nhất) giữa 2 đỉnh trong đồ thị không trọng số, dùng BFS.

Ví dụ:

Input: graph={"A":["B","C"],"B":["A","D"],"C":["A","D"],"D":["B","C","E"],"E":["D"]}, start="A", end="E"
Output: ['A', 'B', 'D', 'E']
Xem đáp án
Đang tải lời giải…

94. Đếm số thành phần liên thông (Connected Components)

Đếm số thành phần liên thông trong một đồ thị vô hướng có thể không liên thông hoàn toàn.

Ví dụ:

Input: {"A": ["B"], "B": ["A"], "C": ["D"], "D": ["C"], "E": []}
Output: 3
Xem đáp án
Đang tải lời giải…

95. Sắp xếp Topo (Topological Sort)

Với một đồ thị có hướng không có chu trình (DAG), sắp xếp các đỉnh theo thứ tự topo bằng thuật toán Kahn (dùng bậc vào - in-degree).

Ví dụ:

Input: {"ao": ["quan"], "quan": ["giay"], "vo": ["quan"], "giay": []}
Output: ['ao', 'vo', 'quan', 'giay']
Xem đáp án
Đang tải lời giải…

96. Unit Test với unittest

Viết hàm cong(a, b) và một bộ test dùng module unittest để kiểm tra hàm hoạt động đúng.

Xem đáp án
Đang tải lời giải…

97. Kiểm tra hàm bằng assert

Viết hàm is_palindrome(s) và dùng các câu lệnh assert để tự kiểm tra nhanh các trường hợp cơ bản.

Xem đáp án
Đang tải lời giải…

Nhóm 14: Lập trình đồng thời (Concurrency) cơ bản

Phần tiêu đề “Nhóm 14: Lập trình đồng thời (Concurrency) cơ bản”

98. threading - Chạy song song đơn giản

GIL (Global Interpreter Lock) là cơ chế trong CPython chỉ cho phép 1 luồng (thread) thực thi code Python tại một thời điểm, nên nhiều thread không thực sự chạy song song mà chỉ xen kẽ nhau rất nhanh. Dùng module threading để chạy 2 tác vụ “song song” theo kiểu này, so sánh với chạy tuần tự.

Xem đáp án
Đang tải lời giải…

99. multiprocessing - Tính tổng song song

Dùng module multiprocessing để chia một list số lớn thành nhiều phần, tính tổng từng phần song song trên nhiều tiến trình (process), rồi cộng kết quả lại.

Xem đáp án
Đang tải lời giải…

100. Mô phỏng nhiều tác vụ chờ với concurrent.futures

Dùng concurrent.futures.ThreadPoolExecutor để tải “giả lập” 5 trang web cùng lúc (mỗi trang mất 1 giây), thay vì tải tuần tự mất 5 giây.

Xem đáp án
Đang tải lời giải…

Bạn đã hoàn thành cả 100 bài cơ bản và 100 bài nâng cao? Quay lại trang Bài tập lập trình - Cơ bản để ôn lại, hoặc thử sức với các bài tập theo từng chủ đề riêng ở sidebar bên trái.

Muốn thử sức với các bài toán phong cách phỏng vấn/LeetCode? Ghé qua Bài tập lập trình - Luyện thuật toán với 200 bài từ Dễ đến Khó, có ví dụ minh họa và ràng buộc chi tiết cho từng bài.