1.颜色分类
给定一个包含红色、白色和蓝色,一共n个元素的数组,原地对他们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
使用整数0、1和2分别表示红色、白色和蓝色。
思路:
- 两次遍历
计数排序,先统计每个元素的个数,然后排序 - 荷兰国旗问题(一次遍历)
用三个指针p0,p2和curr来分别追踪0的最右边界,2的最左边界和当前考虑的元素。
沿数组移动curr指针,若nums[curr] = 0,则将其与nums[p0]互换。若nums[curr] = 2,则将其与nums[p2]互换
void change(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void sortColors(vector<int>& nums) {
int p0 = 0;
int p2 = nums.size() - 1;
int cur = 0;
while(cur <= p2)
{
if(nums[cur] == 0)
{
if(cur == p0)
{
p0++;
cur++;
}
else
{
change(nums[cur], nums[p0]);
p0++;
}
}
else if(nums[cur] == 2)
{
change(nums[cur], nums[p2]);
p2--;
}
else
{
cur++;
}
}
}
2.组合
给定两个整数n和k,返回1…n中所有可能的k个数的组合。
思路:回溯算法
void traceback(int n, int k, int start, vector<int>& temp, vector<vector<int>>& res, vector<int>& flag)
{
if(temp.size() == k)
{
res.push_back(temp);
return;
}
for(int i = start; i <= n; i++)
{
if(flag[i - 1] == 0)
{
temp.push_back(i);
flag[i - 1] = 1;
traceback(n, k, i + 1, temp, res, flag);
flag[i - 1] = 0;
temp.pop_back();
}
}
}
vector<vector<int>> combine(int n, int k) {
vector<vector<int>> res;
vector<int> temp;
vector<int> flag(n, 0);
traceback(n, k, 1, temp, res, flag);
return res;
}