题目描述
给定一个包含红色、白色和蓝色、共 n
个元素的数组 nums
,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0
、 1
和 2
分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。
示例 1:
输入: nums = [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
示例 2:
输入: nums = [2,0,1]
输出: [0,1,2]
提示:
- n == nums.length
- 1 <= n <= 300
- nums[i] 为 0、1 或 2
代码及注释
func sortColors(nums []int) {l, r, mid := 0, len(nums) - 1, 0 // 初始化左指针l、右指针r和中指针midfor mid <= r { // 当中指针未超过右指针时,进行循环if nums[mid] == 0 { // 如果中指针指向的元素是0nums[mid], nums[l] = nums[l], nums[mid] // 将中指针指向的元素与左指针指向的元素交换,并同时移动左指针和中指针l++mid++} else if nums[mid] == 1 { // 如果中指针指向的元素是1mid++ // 直接移动中指针} else { // 如果中指针指向的元素是2nums[mid], nums[r] = nums[r], nums[mid] // 将中指针指向的元素与右指针指向的元素交换,并同时移动右指针r--}}return
}
代码解释
这个函数使用了荷兰国旗问题的解法,也称为三路快排。这种方法可以在一次遍历内将数组中的0、1和2三种元素按照红、白、蓝的顺序排列。
这里的思路是:
- 使用左指针
l
和右指针r
分别指向数组的起始位置和结束位置,中指针mid
用于遍历数组。 - 当中指针
mid
小于或等于右指针r
时,进行循环。 - 如果中指针指向的元素是0,将其与左指针指向的元素交换,并同时移动左指针和中指针。
- 如果中指针指向的元素是1,直接移动中指针。
- 如果中指针指向的元素是2,将其与右指针指向的元素交换,并同时移动右指针。
这个方法的时间复杂度是O(n),其中n是数组nums
的长度。