🚩传送门:力扣题目

题目

给定一个包含红色、白色和蓝色、共 [LC]75. 颜色分类 - 图1 个元素的数组 [LC]75. 颜色分类 - 图2,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 [LC]75. 颜色分类 - 图3[LC]75. 颜色分类 - 图4[LC]75. 颜色分类 - 图5 分别表示红色、白色和蓝色。

必须在不使用库的[LC]75. 颜色分类 - 图6函数的情况下解决这个问题。

示例 1:

输入:nums = [2,0,2,1,1,0] 输出:[0,0,1,1,2,2]

示例 2:

输入:nums = [2,0,1] 输出:[0,1,2]

解题思路:双指针

指针 [LC]75. 颜色分类 - 图7:保证区域[LC]75. 颜色分类 - 图8 全是 [LC]75. 颜色分类 - 图9红色
指针 [LC]75. 颜色分类 - 图10:保证区域[LC]75. 颜色分类 - 图11全是 [LC]75. 颜色分类 - 图12蓝色

指针 [LC]75. 颜色分类 - 图13:遍历数组,遇到[LC]75. 颜色分类 - 图14就和指针 [LC]75. 颜色分类 - 图15交换,遇到[LC]75. 颜色分类 - 图16就和指针 [LC]75. 颜色分类 - 图17交换,需要对交换过来的 [LC]75. 颜色分类 - 图18或者 [LC]75. 颜色分类 - 图19再次判断,当且仅当 [LC]75. 颜色分类 - 图20时结束判断。

  • [LC]75. 颜色分类 - 图21时说明不需要和指针 [LC]75. 颜色分类 - 图22或者指针 [LC]75. 颜色分类 - 图23交换
  • [LC]75. 颜色分类 - 图24时说明交换过来的 [LC]75. 颜色分类 - 图25已经完成了判断,此时应该 [LC]75. 颜色分类 - 图26
  • [LC]75. 颜色分类 - 图27时说明越界了,此时遍历结束,数组有序

复杂度分析

时间复杂度: [LC]75. 颜色分类 - 图28 ,其中 [LC]75. 颜色分类 - 图29[LC]75. 颜色分类 - 图30 的长度。

空间复杂度:[LC]75. 颜色分类 - 图31

官方代码

  1. class Solution {
  2. public static void swap(int[] nums, int i, int j) {
  3. int temp = nums[i];
  4. nums[i] = nums[j];
  5. nums[j] = temp;
  6. }
  7. public static void sortColors(int[] nums) {
  8. int i = 0, j = nums.length - 1;
  9. int index = 0;
  10. while (i <= index && index <= j) {
  11. do {
  12. if (nums[index] == 0) {
  13. swap(nums, i++, index);
  14. } else if (nums[index] == 2) {
  15. swap(nums, j--, index);
  16. }
  17. } while (i <= index && index <= j && nums[index] != 1); // 需要对交换过来的nums[i]||nums[j]再次判断
  18. index++;
  19. }
  20. }
  21. }