Web

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

15 phút đọc
NhiTuyen Tech Blog Team
Thuật Toán & Cấu Trúc Dữ Liệu: Nền Tảng Lập Trình

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!

Algorithms

Ô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 (!!)

Time Complexity

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)
"""

Sorting Algorithms

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

Searching Algorithms

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!

Data Structures

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!

Real World Applications

Đệ 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

Interview Preparation

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

Learning Path

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

Tags:

#Algorithms #Data Structures #Programming #Tin học 12 #Interview Prep

Chia sẻ bài viết:

Bài viết liên quan

Bài viết liên quan 1
Bài viết liên quan 2
Bài viết liên quan 3