Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Sắp xếp mảng chỉ chứa 0, 1, 2 bằng thuật toán Dutch National Flag trong Java

Cho một mảng chỉ chứa các giá trị 0, 1 và 2. Yêu cầu sắp xếp mảng sao cho tất cả các 0 ở đầu, tiếp theo là 1, cuối cùng là 2. Phải sắp xếp tại chỗ (in-place) không dùng mảng phụ.

Chúng ta có thể giải quyết bài toán này bằng thuật toán Dutch National Flag (DNF) – thuật toán cờ Ba Lan, do Edsger Dijkstra đề xuất.

Ví dụ

Đầu vào 1: {2, 0, 0, 1, 2, 1}

Đầu ra: 0 0 1 1 2 2

Đầu vào 2: {0, 1, 1, 2, 1, 1, 0}

Đầu ra: 0 0 1 1 1 1 2

Ý tưởng thuật toán DNF

Thuật toán sử dụng 3 con trỏ để duyệt mảng và hoán đổi các phần tử cần thiết:

  • low: bắt đầu tại đầu mảng (chỉ số 0) – vùng chứa các 0.
  • mid: bắt đầu tại đầu mảng – con trỏ duyệt chính.
  • high: bắt đầu tại cuối mảng (chỉ số n-1) – vùng chứa các 2.

Quy tắc xử lý khi mid <= high:

  • Nếu arr[mid] == 0: hoán đổi arr[mid] với arr[low], tăng cả low và mid.
  • Nếu arr[mid] == 1: chỉ tăng mid (1 đã ở đúng vị trí giữa).
  • Nếu arr[mid] == 2: hoán đổi arr[mid] với arr[high], giảm high (không tăng mid vì phần tử mới tại mid chưa được kiểm tra).

Triển khai Java

public class DNFSort {
    public static void sort(int[] arr) {
        int low = 0, mid = 0, high = arr.length - 1;
        while (mid <= high) {
            if (arr[mid] == 0) {
                swap(arr, mid, low);
                low++;
                mid++;
            } else if (arr[mid] == 1) {
                mid++;
            } else { // arr[mid] == 2
                swap(arr, mid, high);
                high--;
            }
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr = {0, 0, 1, 0, 1, 0, 1, 2, 2};
        sort(arr);
        for (int v : arr) System.out.print(v + " ");
        // Kết quả: 0 0 0 0 1 1 1 1 2
    }
}

Phân tích độ phức tạp

  • Thời gian: O(n) – duyệt mảng một lần.
  • Không gian: O(1) – chỉ dùng vài biến phụ.

Đây là giải pháp tối ưu cho bài toán sắp xếp mảng 3 giá trị riêng biệt.