Thuật Toán & Cấu Trúc Dữ Liệu: Nền Tảng Lập Trình
Từ sách giáo khoa lớp 12 đến phỏng vấn Tech Giants - Hành trình thuật toán của bạn
Thuật Toán & Cấu Trúc Dữ Liệu: Nền Tảng Lập Trình
Bạn đã học thuật toán sắp xếp, tìm kiếm trong lớp 12. Hãy cùng khám phá cách chúng được áp dụng trong thực tế và chuẩn bị cho phỏng vấn lập trình viên!
Ôn Tập Kiến Thức Lớp 12
Thuật Toán Là Gì?
Chú thích: Thuật toán = các bước giải quyết vấn đề, giống công thức toán!
Định nghĩa (SGK Tin học 12):
- Dãy hữu hạn các bước
- Mỗi bước rõ ràng, xác định
- Có input và output
- Kết thúc sau hữu hạn bước
Ví dụ: Tìm số lớn nhất trong dãy
Input: [3, 7, 1, 9, 4]
Output: 9
Thuật Toán Tìm Max (SGK)
# Ví dụ từ sách giáo khoa
def tim_max(a):
"""Tìm số lớn nhất trong danh sách"""
max_val = a[0] # Giả sử phần tử đầu là max
for i in range(1, len(a)):
if a[i] > max_val:
max_val = a[i]
return max_val
# Test
numbers = [3, 7, 1, 9, 4]
print(f"Số lớn nhất: {tim_max(numbers)}") # 9
Phân Tích Thuật Toán
Chú thích: Độ phức tạp O(n) = số phép toán tỉ lệ với n (kích thước dữ liệu)
# Độ phức tạp thời gian (Time Complexity)
def tim_max(a): # O(n) - Linear time
max_val = a[0] # 1 phép toán: O(1)
for i in range(1, len(a)): # n-1 lần lặp
if a[i] > max_val: # So sánh: O(1)
max_val = a[i] # Gán: O(1)
return max_val # O(1)
# Tổng: O(1) + (n-1)*O(1) + O(1) = O(n)
# Các độ phức tạp thường gặp:
"""
O(1) - Constant: Truy cập mảng a[0]
O(log n) - Logarithmic: Binary search
O(n) - Linear: Duyệt mảng
O(n log n) - Linearithmic: Merge sort, Quick sort
O(n²) - Quadratic: Bubble sort, Selection sort
O(2^n) - Exponential: Recursion không tối ưu
O(n!) - Factorial: Hoán vị
"""
# Ví dụ so sánh:
# n = 1,000,000
# O(1): 1 phép toán
# O(log n): ~20 phép toán
# O(n): 1,000,000 phép toán
# O(n²): 1,000,000,000,000 phép toán (!!)
Thuật Toán Sắp Xếp (Sorting)
1. Bubble Sort - Sắp Xếp Nổi Bọt
Chú thích: So sánh 2 phần tử liền nhau, đổi chỗ nếu sai thứ tự. Lặp lại cho đến khi sắp xếp xong.
def bubble_sort(arr):
"""
Sắp xếp nổi bọt - Thuật toán từ SGK
Độ phức tạp: O(n²)
"""
n = len(arr)
# Lặp qua tất cả phần tử
for i in range(n):
# Cờ kiểm tra có hoán đổi không
swapped = False
# Phần tử lớn nhất "nổi" lên cuối
for j in range(0, n - i - 1):
if arr[j] > arr[j + 1]:
# Hoán đổi
arr[j], arr[j + 1] = arr[j + 1], arr[j]
swapped = True
# Nếu không có hoán đổi nào → đã sắp xếp
if not swapped:
break
return arr
# Test
numbers = [64, 34, 25, 12, 22, 11, 90]
print("Trước:", numbers)
bubble_sort(numbers)
print("Sau:", numbers)
# Output: [11, 12, 22, 25, 34, 64, 90]
# Minh họa từng bước:
"""
Pass 1: [34, 25, 12, 22, 11, 64, 90] # 90 đã đúng vị trí
Pass 2: [25, 12, 22, 11, 34, 64, 90] # 64 đã đúng vị trí
Pass 3: [12, 22, 11, 25, 34, 64, 90] # 34 đã đúng vị trí
...
"""
2. Selection Sort - Sắp Xếp Chọn
def selection_sort(arr):
"""
Tìm phần tử nhỏ nhất, đưa lên đầu
Độ phức tạp: O(n²)
"""
n = len(arr)
for i in range(n):
# Tìm phần tử nhỏ nhất trong đoạ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
# Đổi chỗ
arr[i], arr[min_idx] = arr[min_idx], arr[i]
return arr
# Test
numbers = [64, 25, 12, 22, 11]
print("Selection Sort:", selection_sort(numbers.copy()))
3. Insertion Sort - Sắp Xếp Chèn
def insertion_sort(arr):
"""
Chèn từng phần tử vào đúng vị trí (như xếp bài)
Độ phức tạp: O(n²), nhưng nhanh với dữ liệu gần đúng thứ tự
"""
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
# Dịch các phần tử > key sang phải
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
# Chèn key vào vị trí đúng
arr[j + 1] = key
return arr
# Minh họa:
"""
[5, 2, 4, 6, 1, 3]
↑ key=2
[2, 5, 4, 6, 1, 3] # Chèn 2 trước 5
↑ key=4
[2, 4, 5, 6, 1, 3] # Chèn 4 giữa 2 và 5
↑ key=1
[1, 2, 4, 5, 6, 3] # Chèn 1 lên đầu
"""
4. Merge Sort - Sắp Xếp Trộn
Chú thích: Chia nhỏ mảng, sắp xếp từng phần, rồi trộn lại. Thuật toán “Chia để trị”!
def merge_sort(arr):
"""
Merge Sort - Hiệu quả nhất
Độ phức tạp: O(n log n)
"""
if len(arr) <= 1:
return arr
# Chia đôi mảng
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
# Trộn 2 mảng đã sắp xếp
return merge(left, right)
def merge(left, right):
"""Trộn 2 mảng đã sắp xếp"""
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
# Thêm phần còn lại
result.extend(left[i:])
result.extend(right[j:])
return result
# Test
numbers = [38, 27, 43, 3, 9, 82, 10]
print("Merge Sort:", merge_sort(numbers))
# Minh họa:
"""
[38, 27, 43, 3, 9, 82, 10]
↓ Chia
[38, 27, 43, 3] [9, 82, 10]
↓ ↓
[38, 27] [43, 3] [9, 82] [10]
↓ ↓ ↓ ↓ ↓ ↓ ↓
[38][27] [43][3] [9][82] [10]
↓ Trộn
[27, 38] [3, 43] [9, 82] [10]
↓ ↓
[3, 27, 38, 43] [9, 10, 82]
↓ Trộn
[3, 9, 10, 27, 38, 43, 82]
"""
5. Quick Sort - Sắp Xếp Nhanh
def quick_sort(arr):
"""
Quick Sort - Nhanh trong thực tế
Độ phức tạp: O(n log n) trung bình, O(n²) worst case
"""
if len(arr) <= 1:
return arr
# Chọn pivot (phần tử chốt)
pivot = arr[len(arr) // 2]
# Chia thành 3 nhóm
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
# Đệ quy sắp xếp left và right
return quick_sort(left) + middle + quick_sort(right)
# Test
numbers = [10, 7, 8, 9, 1, 5]
print("Quick Sort:", quick_sort(numbers))
So Sánh Các Thuật Toán Sắp Xếp
import time
def benchmark_sort(sort_func, data):
"""Đo thời gian thực thi"""
start = time.time()
sort_func(data.copy())
end = time.time()
return end - start
# Test với mảng ngẫu nhiên
import random
data = [random.randint(1, 1000) for _ in range(1000)]
print("Bubble Sort:", benchmark_sort(bubble_sort, data), "giây")
print("Selection Sort:", benchmark_sort(selection_sort, data), "giây")
print("Insertion Sort:", benchmark_sort(insertion_sort, data), "giây")
print("Merge Sort:", benchmark_sort(merge_sort, data), "giây")
print("Quick Sort:", benchmark_sort(quick_sort, data), "giây")
print("Python sorted():", benchmark_sort(sorted, data), "giây")
"""
Kết quả ước lượng (n=1000):
Bubble Sort: 0.15 giây
Selection Sort: 0.08 giây
Insertion Sort: 0.06 giây
Merge Sort: 0.003 giây ✅
Quick Sort: 0.002 giây ✅
Python sorted(): 0.0001 giây ✅✅ (Timsort - lai Merge + Insertion)
"""
Thuật Toán Tìm Kiếm (Searching)
1. Linear Search - Tìm Kiếm Tuần Tự
def linear_search(arr, target):
"""
Duyệt từng phần tử cho đến khi tìm thấy
Độ phức tạp: O(n)
"""
for i in range(len(arr)):
if arr[i] == target:
return i # Trả về vị trí
return -1 # Không tìm thấy
# Test
numbers = [10, 23, 45, 70, 11, 15]
print(linear_search(numbers, 70)) # 3
print(linear_search(numbers, 100)) # -1
2. Binary Search - Tìm Kiếm Nhị Phân
Chú thích: Chỉ áp dụng cho mảng đã sắp xếp! Chia đôi khoảng tìm kiếm mỗi lần.
def binary_search(arr, target):
"""
Tìm kiếm nhị phân - SGK lớp 12
Độ phức tạp: O(log n) - CỰC NHANH!
"""
left = 0
right = len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid # Tìm thấy!
elif arr[mid] < target:
left = mid + 1 # Tìm nửa phải
else:
right = mid - 1 # Tìm nửa trái
return -1 # Không tìm thấy
# Test (mảng phải sắp xếp trước!)
numbers = [2, 3, 4, 10, 40, 50, 60, 70]
print(binary_search(numbers, 10)) # 3
print(binary_search(numbers, 100)) # -1
# Minh họa:
"""
Tìm 10 trong [2, 3, 4, 10, 40, 50, 60, 70]
↑ mid=40 → Tìm bên trái
[2, 3, 4, 10]
↑ mid=3 → Tìm bên phải
[4, 10]
↑ mid=4 → Tìm bên phải
[10] → Tìm thấy!
Chỉ 4 bước cho mảng 8 phần tử!
Linear search cần tối đa 8 bước.
"""
Binary Search - Phiên Bản Đệ Quy
def binary_search_recursive(arr, target, left, right):
"""Binary search dùng đệ quy"""
if left > right:
return -1
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
return binary_search_recursive(arr, target, mid + 1, right)
else:
return binary_search_recursive(arr, target, left, mid - 1)
# Test
numbers = [2, 3, 4, 10, 40, 50, 60, 70]
result = binary_search_recursive(numbers, 10, 0, len(numbers) - 1)
print(result) # 3
Cấu Trúc Dữ Liệu (Data Structures)
1. Array/List - Mảng
# Mảng cơ bản
arr = [1, 2, 3, 4, 5]
# Truy cập: O(1)
print(arr[0]) # 1
# Thêm cuối: O(1)
arr.append(6)
# Thêm đầu/giữa: O(n)
arr.insert(0, 0)
# Xóa: O(n)
arr.remove(3)
# Tìm kiếm: O(n)
print(3 in arr)
# Ứng dụng:
# - Lưu điểm học sinh
# - Lưu sản phẩm
# - Todo list
2. Stack - Ngăn Xếp
Chú thích: LIFO = Last In First Out (vào sau ra trước), như chồng sách!
class Stack:
"""Stack - Ngăn xếp"""
def __init__(self):
self.items = []
def push(self, item):
"""Thêm phần tử lên đỉnh"""
self.items.append(item)
def pop(self):
"""Lấy phần tử ở đỉnh"""
if not self.is_empty():
return self.items.pop()
return None
def peek(self):
"""Xem phần tử đỉnh (không xóa)"""
if not self.is_empty():
return self.items[-1]
return None
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
# Test
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.pop()) # 3 (vào sau ra trước)
print(stack.peek()) # 2
# Ứng dụng thực tế:
# - Undo/Redo trong editor
# - Back button trong browser
# - Kiểm tra ngoặc đúng: ({[]})
# - Đệ quy (call stack)
3. Queue - Hàng Đợi
Chú thích: FIFO = First In First Out (vào trước ra trước), như xếp hàng!
from collections import deque
class Queue:
"""Queue - Hàng đợi"""
def __init__(self):
self.items = deque()
def enqueue(self, item):
"""Thêm vào cuối hàng"""
self.items.append(item)
def dequeue(self):
"""Lấy từ đầu hàng"""
if not self.is_empty():
return self.items.popleft()
return None
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
# Test
queue = Queue()
queue.enqueue("A")
queue.enqueue("B")
queue.enqueue("C")
print(queue.dequeue()) # A (vào trước ra trước)
print(queue.dequeue()) # B
# Ứng dụng:
# - Hàng đợi in ấn
# - Task queue (Celery, RabbitMQ)
# - Breadth-First Search (BFS)
# - Xử lý requests
4. Linked List - Danh Sách Liên Kết
class Node:
"""Node của linked list"""
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
"""Linked List"""
def __init__(self):
self.head = None
def append(self, data):
"""Thêm node mới vào cuối"""
new_node = Node(data)
if not self.head:
self.head = new_node
return
current = self.head
while current.next:
current = current.next
current.next = new_node
def prepend(self, data):
"""Thêm node mới vào đầu"""
new_node = Node(data)
new_node.next = self.head
self.head = new_node
def delete(self, data):
"""Xóa node có giá trị data"""
if not self.head:
return
if self.head.data == data:
self.head = self.head.next
return
current = self.head
while current.next:
if current.next.data == data:
current.next = current.next.next
return
current = current.next
def display(self):
"""In ra linked list"""
elements = []
current = self.head
while current:
elements.append(str(current.data))
current = current.next
print(" -> ".join(elements))
# Test
ll = LinkedList()
ll.append(1)
ll.append(2)
ll.append(3)
ll.prepend(0)
ll.display() # 0 -> 1 -> 2 -> 3
ll.delete(2)
ll.display() # 0 -> 1 -> 3
# So sánh Array vs Linked List:
"""
Array Linked List
Access O(1) O(n)
Insert O(n) O(1) (nếu biết vị trí)
Delete O(n) O(1) (nếu biết vị trí)
Memory Compact Scattered + pointers
"""
5. Hash Table - Bảng Băm
class HashTable:
"""Hash Table đơn giản"""
def __init__(self, size=10):
self.size = size
self.table = [[] for _ in range(size)]
def _hash(self, key):
"""Hash function"""
return hash(key) % self.size
def set(self, key, value):
"""Thêm/cập nhật key-value"""
index = self._hash(key)
# Kiểm tra key đã tồn tại
for pair in self.table[index]:
if pair[0] == key:
pair[1] = value
return
# Thêm mới
self.table[index].append([key, value])
def get(self, key):
"""Lấy value theo key"""
index = self._hash(key)
for pair in self.table[index]:
if pair[0] == key:
return pair[1]
return None
def delete(self, key):
"""Xóa key"""
index = self._hash(key)
for i, pair in enumerate(self.table[index]):
if pair[0] == key:
del self.table[index][i]
return
# Test
ht = HashTable()
ht.set("name", "John")
ht.set("age", 25)
ht.set("city", "Hanoi")
print(ht.get("name")) # John
print(ht.get("age")) # 25
# Python dict là hash table!
student = {"name": "Nguyen Van A", "age": 18, "grade": 12}
print(student["name"]) # O(1) - Rất nhanh!
Bài Toán Thực Tế
1. Tìm Kiếm Trong Dictionary
# Từ điển Anh-Việt (đã sắp xếp)
dictionary = [
("apple", "quả táo"),
("book", "quyển sách"),
("cat", "con mèo"),
("dog", "con chó"),
("elephant", "con voi")
]
def search_word(word):
"""Binary search trong từ điển"""
left, right = 0, len(dictionary) - 1
while left <= right:
mid = (left + right) // 2
mid_word = dictionary[mid][0]
if mid_word == word:
return dictionary[mid][1]
elif mid_word < word:
left = mid + 1
else:
right = mid - 1
return "Không tìm thấy"
print(search_word("cat")) # con mèo
print(search_word("elephant")) # con voi
2. Xếp Hạng Học Sinh
students = [
{"name": "An", "score": 8.5},
{"name": "Bình", "score": 9.0},
{"name": "Cường", "score": 7.5},
{"name": "Dung", "score": 9.5},
]
# Sắp xếp theo điểm giảm dần
sorted_students = sorted(students, key=lambda x: x["score"], reverse=True)
print("Bảng xếp hạng:")
for i, student in enumerate(sorted_students, 1):
print(f"{i}. {student['name']}: {student['score']}")
"""
Output:
1. Dung: 9.5
2. Bình: 9.0
3. An: 8.5
4. Cường: 7.5
"""
3. Undo/Redo trong Text Editor
class TextEditor:
"""Text editor với undo/redo"""
def __init__(self):
self.text = ""
self.undo_stack = Stack()
self.redo_stack = Stack()
def write(self, text):
"""Viết text"""
self.undo_stack.push(self.text)
self.text += text
# Clear redo stack khi có thao tác mới
self.redo_stack = Stack()
def undo(self):
"""Hoàn tác"""
if not self.undo_stack.is_empty():
self.redo_stack.push(self.text)
self.text = self.undo_stack.pop()
def redo(self):
"""Làm lại"""
if not self.redo_stack.is_empty():
self.undo_stack.push(self.text)
self.text = self.redo_stack.pop()
def display(self):
print(f"Text: {self.text}")
# Test
editor = TextEditor()
editor.write("Hello")
editor.display() # Hello
editor.write(" World")
editor.display() # Hello World
editor.undo()
editor.display() # Hello
editor.redo()
editor.display() # Hello World
4. Autocomplete - Gợi Ý Từ
def autocomplete(words, prefix):
"""Tìm các từ bắt đầu bằng prefix"""
# Sắp xếp để dùng binary search
words.sort()
suggestions = []
for word in words:
if word.startswith(prefix):
suggestions.append(word)
elif word > prefix: # Đã qua phạm vi
break
return suggestions
# Test
words = ["apple", "application", "apply", "banana", "app", "appreciate"]
print(autocomplete(words, "app"))
# Output: ['app', 'apple', 'application', 'apply']
# Google search sử dụng Trie data structure cho autocomplete!
Đệ Quy (Recursion)
Chú thích: Hàm gọi chính nó - một trong những khái niệm quan trọng nhất!
Ví Dụ Cơ Bản
# 1. Giai thừa
def factorial(n):
"""n! = n × (n-1) × ... × 1"""
if n <= 1: # Base case
return 1
return n * factorial(n - 1) # Recursive case
print(factorial(5)) # 120 = 5 × 4 × 3 × 2 × 1
# 2. Fibonacci
def fibonacci(n):
"""Dãy Fibonacci: 0, 1, 1, 2, 3, 5, 8, 13, ..."""
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print([fibonacci(i) for i in range(10)])
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
# 3. Tính tổng mảng
def sum_array(arr):
"""Tổng các phần tử"""
if len(arr) == 0:
return 0
return arr[0] + sum_array(arr[1:])
print(sum_array([1, 2, 3, 4, 5])) # 15
Đệ Quy vs Vòng Lặp
# Tính tổng 1 đến n
# Dùng đệ quy
def sum_recursive(n):
if n == 1:
return 1
return n + sum_recursive(n - 1)
# Dùng vòng lặp
def sum_iterative(n):
total = 0
for i in range(1, n + 1):
total += i
return total
print(sum_recursive(100)) # 5050
print(sum_iterative(100)) # 5050
# Vòng lặp thường nhanh hơn và ít tốn bộ nhớ
# Đệ quy dễ hiểu hơn với một số bài toán (trees, graphs)
Bài Tập Phỏng Vấn
Bài 1: Two Sum
def two_sum(nums, target):
"""
Tìm 2 số có tổng = target
LeetCode #1 - Easy
"""
seen = {} # {value: index}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return []
# Test
print(two_sum([2, 7, 11, 15], 9)) # [0, 1] vì 2 + 7 = 9
print(two_sum([3, 2, 4], 6)) # [1, 2] vì 2 + 4 = 6
Bài 2: Valid Parentheses
def is_valid_parentheses(s):
"""
Kiểm tra ngoặc hợp lệ
LeetCode #20 - Easy
"""
stack = []
pairs = {')': '(', '}': '{', ']': '['}
for char in s:
if char in pairs.values(): # Ngoặc mở
stack.append(char)
elif char in pairs.keys(): # Ngoặc đóng
if not stack or stack[-1] != pairs[char]:
return False
stack.pop()
return len(stack) == 0
# Test
print(is_valid_parentheses("()")) # True
print(is_valid_parentheses("()[]{}")) # True
print(is_valid_parentheses("(]")) # False
print(is_valid_parentheses("([)]")) # False
print(is_valid_parentheses("{[]}")) # True
Bài 3: Reverse String
def reverse_string(s):
"""Đảo ngược chuỗi"""
# Cách 1: Python built-in
return s[::-1]
def reverse_string_iterative(s):
"""Dùng vòng lặp"""
result = ""
for char in s:
result = char + result
return result
def reverse_string_recursive(s):
"""Dùng đệ quy"""
if len(s) <= 1:
return s
return s[-1] + reverse_string_recursive(s[:-1])
# Test
print(reverse_string("hello")) # olleh
Bài 4: Find Maximum Subarray
def max_subarray_sum(arr):
"""
Tìm tổng lớn nhất của dãy con liên tiếp
Kadane's Algorithm
LeetCode #53
"""
max_sum = current_sum = arr[0]
for num in arr[1:]:
# Chọn: tiếp tục dãy cũ hay bắt đầu dãy mới?
current_sum = max(num, current_sum + num)
max_sum = max(max_sum, current_sum)
return max_sum
# Test
print(max_subarray_sum([-2, 1, -3, 4, -1, 2, 1, -5, 4])) # 6 ([4,-1,2,1])
print(max_subarray_sum([1])) # 1
print(max_subarray_sum([5, 4, -1, 7, 8])) # 23
Chuẩn Bị Phỏng Vấn
Nền Tảng Luyện Tập
LeetCode (https://leetcode.com):
- 2000+ bài toán
- Easy, Medium, Hard
- Discuss solutions
- Mock interviews
HackerRank (https://hackerrank.com):
- Nhiều ngôn ngữ
- Certification tests
- Company challenges
Codeforces (https://codeforces.com):
- Competitive programming
- Contests
- Rating system
Roadmap Học Tập
Week 1-2: Cơ Bản
- Array & String manipulation
- Two pointers
- Sliding window
Week 3-4: Searching & Sorting
- Binary search variations
- Sorting algorithms
- Quick select
Week 5-6: Data Structures
- Stack & Queue
- Linked List
- Hash Table
Week 7-8: Recursion & DP
- Recursion patterns
- Dynamic Programming basics
- Memoization
Week 9-10: Trees & Graphs
- Binary trees
- BFS & DFS
- Graph algorithms
Week 11-12: Advanced
- Greedy algorithms
- Backtracking
- Bit manipulation
Tips Phỏng Vấn
1. Hiểu rõ đề bài:
- Đọc kỹ requirements
- Hỏi clarification questions
- Xác nhận input/output
2. Suy nghĩ trước khi code:
- Giải thích approach
- Phân tích độ phức tạp
- Vẽ diagram nếu cần
3. Code clean & test:
- Viết code dễ đọc
- Test edge cases
- Tối ưu nếu có thể
4. Communication:
- Nói ra suy nghĩ
- Giải thích từng bước
- Chấp nhận feedback
Kết Luận
Thuật toán & Cấu trúc dữ liệu là nền tảng của:
- ✅ Problem solving skills
- ✅ Interview preparation (FAANG)
- ✅ Optimize performance
- ✅ System design
- ✅ Competitive programming
# Journey từ lớp 12 đến Tech Giants
journey = {
"Lớp 12": ["Bubble Sort", "Linear Search", "Array basics"],
"Đại học": ["Advanced algorithms", "Data structures", "Complexity analysis"],
"Intern": ["LeetCode", "Mock interviews", "Real projects"],
"Engineer": ["System design", "Optimization", "Mentoring"],
"Tech Lead": ["Architecture", "Trade-offs", "Leadership"]
}
# Start today! 💪
print("From SGK Tin học 12 to Tech Giants! 🚀")
Bạn đã giải được bao nhiêu bài trên LeetCode? Chia sẻ profile! 💻
Tags
#Algorithms #DataStructures #Programming #LeetCode #Interview #TinHoc12