0075. Sort Colors

  • Nhãn: Mảng, Con trỏ kép, Sắp xếp
  • Độ khó: Trung bình

Tóm tắt đề bài

Mô tả: Cho một mảng số nguyên , các phần tử chỉ có thể là , , , tương ứng với màu đỏ, màu trắng và màu xanh lam.

Yêu cầu: Sắp xếp mảng sao cho các phần tử màu đỏ nằm trước, màu trắng nằm ở giữa và màu xanh lam nằm cuối.

Giải thích:

  • Yêu cầu không sử dụng các hàm thư viện tiêu chuẩn và chỉ sử dụng không gian hằng số, chỉ cần duyệt mảng một lần để giải quyết.
  • là độ dài của mảng .
  • .
  • có giá trị là , hoặc .

Ví dụ:

  • Ví dụ 1:
Input: nums = [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]
  • Ví dụ 2:
Input: nums = [2,0,1]
Output: [0,1,2]

Ý tưởng giải quyết

Ý tưởng 1: Con trỏ kép + ý tưởng sắp xếp nhanh

Trong thuật toán sắp xếp nhanh, quá trình phân vùng sử dụng con trỏ kép để di chuyển các phần tử lớn hơn phần tử cơ sở sang bên phải của mảng và di chuyển các phần tử nhỏ hơn phần tử cơ sở sang bên trái của mảng. Như vậy, mảng được chia thành ba phần: phần nhỏ hơn phần tử cơ sở, phần tử cơ sở và phần lớn hơn phần tử cơ sở.

Chúng ta có thể áp dụng quá trình phân vùng trong thuật toán sắp xếp nhanh để giải quyết bài toán này. Chọn số làm phần tử cơ sở , sau đó chia mảng thành ba phần: (phần nhỏ hơn ), (phần bằng ) và (phần lớn hơn ). Các bước cụ thể như sau:

  1. Sử dụng hai con trỏ , đại diện cho cuối phần tử màu đỏ đã được xử lý, đại diện cho đầu phần tử màu xanh lam đã được xử lý.
  2. Sử dụng một con trỏ để duyệt qua mảng, nếu gặp , hoán đổi , đồng thời di chuyển sang phải. Nếu gặp , hoán đổi , đồng thời di chuyển sang trái.
  3. Tiếp tục duyệt qua mảng cho đến khi di chuyển đến vị trí thì dừng. Sau khi duyệt xong, lúc này, phần bên trái của là màu đỏ, phần bên phải của là màu xanh lam.

Lưu ý: Khi di chuyển, cần kiểm tra vị trí của , vì phần bên trái của là mảng đã được xử lý, nên cần kiểm tra vị trí của có nhỏ hơn hay không, nếu nhỏ hơn thì cần cập nhật vị trí của .

Ý tưởng 1: Code

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        left = 0
        right = len(nums) - 1
        index = 0
        while index <= right:
            if index < left:
                index += 1
            elif nums[index] == 0:
                nums[index], nums[left] = nums[left], nums[index]
                left += 1
            elif nums[index] == 2:
                nums[index], nums[right] = nums[right], nums[index]
                right -= 1
            else:
                index += 1

Ý tưởng 1: Độ phức tạp

  • Độ phức tạp thời gian: .
  • Độ phức tạp không gian: .