# 75. 颜色分类

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

# 解题思路

其实本质就是一个排序问题,而且只有三个值,其中 0 可以总是放到前面,而是 2 总是放在后面。

所以可以遍历数组将 0 移动,跳过 2,然后记住最后一个 1 的索引,将遇到的 1 插入到该索引后,并更新索引。

var sortColors = function (nums) {
  var i1 = 0
  var item

  for (var i = 0; i < nums.length; i++) {
    item = nums[i]

    if (item === 0) {
      nums.unshift(...nums.splice(i, 1))
      i1++
    } else if (item === 1) {
      if (i1 >= 0) {
        nums.splice(i1, 0, ...nums.splice(i, 1))
      }

      i1++
    }
  }
}

类似的思路,我们将已就绪的最后一个 0 和 1 的下一位索引 i0, i1 都初始化为 0,然后以索引 i 遍历数组。

对于遇到的 2 同样直接跳过,当遇到 0 时则需要将 i 与记录的 i0 进行交换,对于已就绪的 0 后面跟着一排 1 又隔着 2 的情况(如 0 1 1 2 0),交换后面的 0 时会把 1 给置换出去了,所以需要判断一下,当 p0 < p1 时需要对 1 进行一次交换。

另外由于外前面置换 0 会同时影响 0 和 1 的下一位索引,所以 2 者都需要更新。

而当遇到 1 时则仅需要和 p1 进行一次交换,并更新它的值。

impl Solution {
    pub fn sort_colors(nums: &mut Vec<i32>) {
        let mut p0 = 0;
        let mut p1 = 0;

        for i in 0..nums.len() {
            if nums.get(i).unwrap() == &0 {
                nums.swap(p0, i);

                if (p0 < p1) {
                    nums.swap(p1, i);
                }

                p0 += 1;
                p1 += 1;
            } else if nums.get(i).unwrap() == &1 {
                nums.swap(p1 ,i);
                p1 += 1;
            }
        }
    }
}

更多解法可参考官网。

# 参考