thumbnailsearchingbaitapday2.

DSA Từ A-Z Day 2: Search (Bài Tập)

⚠️

Lưu ý: Kiến Thức Tiên Quyết

Các bạn nên đọc và nắm vững phần lý thuyết dưới đây trước khi bắt đầu làm bài tập nhé!

Author: Loser1 from Learning AI With Losers

Lời Mở Đầu

Chào các bạn losers thân mến! Loser1 từ Learning AI With Losers quay trở lại đây! 👋

Sau khi đã cùng nhau khám phá lý thuyết về Linear Search và Binary Search trong phần trước, đã đến lúc chúng ta thử sức với những bài tập thực tế. Và hôm nay, mình đã chọn lọc những bài tập “chất lượng” từ đề thi của trường HCMUS để các bạn luyện tập! 🎯

Về Nguồn Bài Tập

Các bài tập trong phần này được chọn lọc từ đề thi của trường Đại học Khoa học Tự nhiên (HCMUS), được biết đến với:

  • Độ khó tăng dần từ cơ bản đến nâng cao
  • Bao quát đầy đủ các kỹ thuật tìm kiếm
  • Đặc biệt chú trọng vào tư duy thuật toán

Cấu Trúc Bài Giảng

Mình sẽ chia bài tập thành các phần:

  1. Bài Tập Cơ Bản:
  • Tìm tổng hai phần tử
  • Binary Search cơ bản và đệ quy
  1. Bài Tập Nâng Cao:
  • Tìm kiếm trong mảng xoay
  • Đếm số giá trị thỏa điều kiện
  • So sánh các phương pháp
  1. Câu Hỏi Lý Thuyết:
  • Điều kiện áp dụng Binary Search
  • Phân tích độ phức tạp

Cách Tiếp Cận

Với mỗi bài tập, mình sẽ:

  1. 📝 Phân tích đề bài chi tiết
  2. 💡 Đưa ra hints và gợi ý
  3. ✍️ Trình bày lời giải từng bước
  4. 🎯 Thảo luận độ phức tạp
  5. 🔍 Nêu các trường hợp đặc biệt cần lưu ý

Lời Khuyên Trước Khi Bắt Đầu

  1. Đọc kỹ đề bài và hiểu rõ yêu cầu
  2. Thử giải trước khi xem lời giải
  3. Không vội vàng khi gặp khó khăn
  4. Tự implement lại code sau khi đọc lời giải

Chuẩn Bị

  • ⌨️ IDE/Editor của bạn
  • 📒 Giấy bút để làm bài
  • 🧠 Kiến thức từ phần lý thuyết trước
  • ⏰ Khoảng 2-3 giờ để tập trung

Nhắc Lại Kiến Thức

Nếu bạn chưa đọc phần lý thuyết về Linear Search và Binary Search, hãy đọc lại tại đây để có nền tảng vững chắc trước khi làm bài tập nhé!

Let’s solve some problems! 🚀

Note: Các bài tập được sắp xếp theo độ khó tăng dần. Hãy giải tuần tự để xây dựng tư duy một cách vững chắc nhé!


Đề 1: Tìm tổng hai phần tử trong hai mảng bằng k

Đề bài:
Viết hàm kiểm tra xem có tồn tại hai phần tử (a) trong mảng (A) và (b) trong mảng (B) sao cho (a + b = k).
Yêu cầu sử dụng Merge Sort và Binary Search.

Đáp án:

C++
void Merge(int A1[], int A2[]) { 
    // Triển khai logic merge
}

void MergeSort(int Arr[], int n, int left, int right) { 
    // Triển khai logic MergeSort
}

int Sum(int A[], int B[], int n, int k) {
    MergeSort(A, n, 0, n-1); 
    MergeSort(B, n, 0, n-1);

    int left = 0;
    int right = n-1;

    while (left <= n-1 && right >= 0) {
        if (A[left] + B[right] == k) {
            return 1; 
        } else if (A[left] + B[right] > k) {
            right--; 
        } else {
            left++; 
        }
    }
    return 0; 
}

Đề 2: Tìm kiếm trong mảng xoay

Đề bài:
Viết hàm tìm vị trí của phần tử (k) trong mảng đã bị xoay (ví dụ: ([4,5,6,7,0,1,2])).

Đáp án:

C++
int searchArray(int a[], int n, int k) {<br>    int left = 0, right = n - 1;<br>    while (left <= right) {<br>        int mid = left + (right - left) / 2;<br>        if (a[mid] == k) return mid;<br>        <br>        if (a[left] <= a[mid]) { // Nửa trái đã được sắp xếp<br>            if (a[left] <= k && k < a[mid]) <br>                right = mid - 1;   // Tìm bên trái<br>            else <br>                left = mid + 1;    // Tìm bên phải<br>        } <br>        else { // Nửa phải đã được sắp xếp<br>            if (a[mid] < k && k <= a[right]) <br>                left = mid + 1;    // Tìm bên phải<br>            else <br>                right = mid - 1;   // Tìm bên trái<br>        }<br>    }<br>    return -1;<br>}<br><br>

Đề 3: Đếm số giá trị thỏa điều kiện xuất hiện

Đề bài:

Đáp án:

C++
// Hàm tính số lần xuất hiện tối thiểu của k
int min_appearances(int k) {
    return k * (int)sqrt(k) + (k / 2);
}

// Tìm chỉ số đầu tiên lớn hơn k (Upper Bound)
int UpperBound(int a[], int L, int R, int k) {
    int ans = R + 1;
    while (L <= R) {
        int mid = L + (R - L) / 2;
        if (a[mid] > k) {
            ans = mid;
            R = mid - 1;
        } else {
            L = mid + 1;
        }
    }
    return ans;
}

// Hàm chính tính số giá trị khác nhau thỏa mãn
int Cau2(int a[], int L, int R) {
    if (L > R) return 0;

    int count = 0;

    while (L <= R) {
        int key = a[L];  // Lấy giá trị hiện tại
        int min_occur = min_appearances(key);  // Tính số lần xuất hiện tối thiểu của key

        // Tìm vị trí cuối cùng của key
        int upper_pos = UpperBound(a, L, R, key);
        int actual_occur = upper_pos - L;

        // Kiểm tra nếu số lần xuất hiện thực tế của key lớn hơn hoặc bằng min_occur
        if (actual_occur >= min_occur) {
            count++;  // Tăng số lượng giá trị thỏa mãn
        }

        // Nhảy tới giá trị khác
        L = upper_pos;
    }

    return count;
}

Độ phức tạp:

Với mỗi giá trị duy nhất, ta thực hiện binary search một lần: O(log n)

Số giá trị duy nhất tối đa là O(sqrt(n)) do điều kiện về số lần xuất hiện

Do đó độ phức tạp tổng thể là O(sqrt(n) * log n) < O(n)


Đề 4: Binary Search đệ quy

Đề bài:

Đáp án : 
	Khởi đầu : 
	Cho A[] , tìm 6  
L = 0 ,  R = 9 
	Vòng While : 
	 	Lần 1 : L = 0  , R = 9 , M = (L+R)/2 = (0+9)/2 = 4 
			A[M] = A[4] = 4 
			Do A[M]  < 6 
			L = M + 1  =  5 
		Lần 2 : L = 5 , R = 9  , M = (5+9)/2 = 7 
			A[M] = A[7] =  7 
			Do A[M] > 6
			R = M-1 = 7-1 = 6
		Lần 3 : L = 5 , R  = 6 , M = (5+6)/2 = 5 
			A[M] = A[5] = 5 
			Do A[M] > 5  : 
			L = M + 1   = 5+1 = 6 
		Lần 4 : L = 6 , R = 6  , M = 6 
			A[M] bằng 6 
			Đã tìm thấy 6 trong mảng  tại vị trí 3





Đề 4.5 : Binary search đệ quy

Code:

C++
int BinarySearch(int a[], int L, int R, int k) {
    if (L > R) return -1;
    int M = L + (R - L) / 2;
    if (a[M] == k) return M;
    else if (a[M] > k) return BinarySearch(a, L, M-1, k);
    else return BinarySearch(a, M+1, R, k);
}

Đề 5: So sánh phương pháp tìm từ chung

Đề bài:


Cho hai văn bản (A) và (B). So sánh hai phương pháp tìm từ chung:
a) Thơi gian nhanh nhất
b) Bộ nhớ ít nhất

C++
Bài 2 : 
 a) 
Sử dụng bảng băm (Hash Table, có thể sử dụng unordered set):
Đưa tất cả các từ của văn bản B vào một bảng băm.
Duyệt qua từng từ của văn bản A và kiểm tra xem từ đó có tồn tại trong bảng băm của B không.

Độ phức tạc thời gian: O(n + m), với n là số từ của A và m là số từ của B.	
Space : O(n+m) 
b) Duyệt Trâu (hoặc sort rồi 2 con trỏ)  . mỗi từ trong B duyệt qua A 1 lần ….
Space : O(1) 
Time  : O(n*m) 

Đề 6

Đề 7

Đáp án

Câu 6: Điều kiện để có thể thực hiện thao tác tìm kiếm nhị phân

Để có thể thực hiện thao tác tìm kiếm nhị phân, cây nhị phân phải được sắp xếp theo thứ tự tăng dần hoặc giảm dần.

Câu 10: Độ phức tạp của thao tác tìm kiếm nhị phân

Độ phức tạp của thao tác tìm kiếm nhị phân là O(log n), nghĩa là độ phức tạp tăng theo logarit của kích thước dữ liệu.

Câu 7: Độ phức tạp khi thực hiện quá trình gồm 3 bước xử lý

Nếu một quá trình gồm 3 bước xử lý với độ phức tạp lần lượt là O(n^2), O(n^3) và O(n log n), thì độ phức tạp tổng thể của quá trình đó sẽ là O(n^3), vì độ phức tạp của bước xử lý lớn nhất sẽ chi phối độ phức tạp tổng thể.

Trong các câu hỏi liên quan đến tìm kiếm, việc hiểu rõ các khái niệm như tìm kiếm nhị phân, độ phức tạp của các thuật toán tìm kiếm là rất quan trọng. Hy vọng những giải thích trên sẽ giúp bạn hiểu rõ hơn về các vấn đề này.

quyminhhuy0@gmail.com
quyminhhuy0@gmail.com
Articles: 34

Newsletter Updates

Enter your email address below and subscribe to our newsletter

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
AI Assistant
Hi! How can I help you today?
Hoodies j alexander martin.