大家好,我是小卡皮巴拉
文章目录
目录
力扣题目:颜色分类
题目描述
解题思路
问题理解
算法选择
具体思路
解题要点
完整代码(C++)
兄弟们共勉 !!!
每篇前言
博客主页:小卡皮巴拉
咱的口号:小比特,大梦想
作者请求:由于博主水平有限,难免会有错误和不准之处,我也非常渴望知道这些错误,恳请大佬们批评斧正。
原题链接:75. 颜色分类 - 力扣(LeetCode)
给定一个包含红色、白色和蓝色、共 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]
本题要求对一个包含 0、1、2 三种元素的数组进行原地排序,使得相同颜色(即相同数字)的元素相邻,并且按照 0、1、2 的顺序排列,同时不能使用库内置的 sort
函数。
采用三指针法。使用三个指针 left
、right
和 i
来对数组进行划分和排序,通过一次遍历数组,将 0 交换到数组的左边,2 交换到数组的右边,1 自然就会在中间,从而实现排序。
初始化指针:
初始化 left
指针为 -1,用于标记 0 区域的右边界。
初始化 right
指针为数组的大小,用于标记 2 区域的左边界。
初始化 i
指针为 0,用于遍历数组。
遍历数组:
当 i
小于 right
时,执行以下操作:
当前元素为 0:如果 nums[i]
等于 0,将 left
指针右移一位,然后交换 nums[left]
和 nums[i]
,再将 i
指针右移一位。这样可以将 0 元素交换到 0 区域。
当前元素为 2:如果 nums[i]
等于 2,将 right
指针左移一位,然后交换 nums[right]
和 nums[i]
。注意此时 i
指针不移动,因为交换过来的元素还未处理。
当前元素为 1:如果 nums[i]
等于 1,直接将 i
指针右移一位,因为 1 元素不需要交换,会自然地留在中间。
完成排序:
当 i
等于 right
时,遍历结束,数组已经按照 0、1、2 的顺序排列好。
指针的含义和移动:明确 left
、right
和 i
三个指针的含义,根据当前元素的值正确移动指针,确保 0 元素在左边,2 元素在右边,1 元素在中间。
交换元素:使用 swap
函数交换元素的位置,注意交换后指针的移动情况。
遍历条件:遍历数组时,i
指针的范围是小于 right
,因为 right
之后的元素已经是排好序的 2 元素。
class Solution {
public:
void sortColors(vector& nums)
{
// left 指针用于标记 0 区域的右边界,初始化为 -1,表示还没有 0 元素
int left = -1;
// right 指针用于标记 2 区域的左边界,初始化为数组大小,表示还没有 2 元素
int right = nums.size();
// i 指针用于遍历数组
for(int i = 0; i < right;)
{
// 如果当前元素是 0
if(nums[i] == 0)
{
// 将 0 元素交换到 0 区域,left 指针右移一位
swap(nums[++left], nums[i]);
// 交换后 i 指针也右移一位
i++;
}
// 如果当前元素是 2
else if(nums[i] == 2)
{
// 将 2 元素交换到 2 区域,right 指针左移一位
swap(nums[--right], nums[i]);
// 注意这里 i 不移动,因为交换过来的元素还未处理
}
// 如果当前元素是 1
else
{
// 1 元素不需要交换,直接将 i 指针右移一位
i++;
}
}
}
};
码字不易,求个三连
抱拳了兄弟们!