75. 颜色分类

234 阅读1分钟

方法一:用排序算法,O(NlogN)

方法二:单指针,扫两遍,O(N)

第一遍挪0,第二遍挪1

class Solution {
    public void sortColors(int[] nums) {
        int p = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == 0) {
                swap(nums, i, p);
                p++;
            }
        }
        for (int i = p; i < nums.length; i++) {
            if (nums[i] == 1) {
                swap(nums, i, p);
                p++;
            }
        }
    }
    public void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

方法二:双指针,扫一遍,O(N)

  • i从左往右扫,指针p0是下一个放0的位置,指针p1是下一个放1的位置。
  • 遇到了0,swap,然后p0和p1都+1,
    • 下一个放0的位置+1
    • 因为1肯定要排在0后面,所以p1也要+1
    • 需要处理1被0覆盖的情况。
  • 遇到了1,swap,只有p1 + 1
class Solution {
    public void sortColors(int[] nums) {
        // p0为存放下一个0的位置,p1为存放下一个1的位置, cur为遍历指针
        int p0 = 0, p1 = 0, cur = 0;
        while (cur < nums.length) {
            if (nums[cur] == 0) {
                //这时,把nums[i]=0换回前面会覆盖1,需要再把nums[i]=1换到下一个放1的位置
                if (p0 < p1) {
                    swap(nums, cur, p0);
                    swap(nums, cur, p1);
                    p0++;
                    p1++;
                } else {
                    swap(nums, cur, p0);
                    p0++;//填充下一个0的位置加一
                    p1++;//填充下一个1的位置加一
                }
            } else if (nums[cur] == 1) {
                swap(nums, cur, p1);//填充下一个1的位置+1,填充下一个0的位置不变
                p1++;
            }
            cur++;
        }
    }
    
    public void swap(int[] nums, int m, int n) {
        int tmp = nums[m];
        nums[m] = nums[n];
        nums[n] = tmp;
    }

    //由于一开始p0=p1,所以当p1 > p0 时,说明p1肯定已经向右移动了,p0的位置上必然是1
                //这时候如果swap一下i和p0,相当于把1又换出去了,然后应该把1再换到下一个期待1的位置,即p1
                //        p0  p1      i
                //  +-------------------+
                //  | 0 | 1 |   |   | 0 |
                //  +-------------------+

}