- 荷兰国旗问题
这个问题很简单,遍历一遍整个数组,统计一下没个数字的个数,搞定。
//include <algorithm>// swap需要
class Solution {
public:
void sortColors(vector<int>& nums) {
vector<int> v(3,0);
for(int &x:nums)
v[x]++;
int i=0;
for(int j=0;j<3;j++)
{
while(v[j]--)
nums[i++]=j;
}
}
};
下面是贪心算法部分
- 分发小饼干
我手写了排序,发现超时,嘤嘤嘤。。。
class Solution {
public:
void quicksort(vector<int> & v, int i, int j)
{
if(i>=j)
return;
int oj=j;//此处bug找了一个小时!!
int flag = v[i];
while(i<j)
{
while(v[j]>=flag && i<j)
j--;
if(i<j)
v[i++]=v[j];
while(v[i]<=flag && i<j)
i++;
if(i<j)
v[j--]=v[i];
}
v[i]=flag;
quicksort(v, 0, i-1);
quicksort(v, i+1, oj); //不要写成j!!!
}
int findContentChildren(vector<int>& g, vector<int>& s) {
quicksort(g, 0, g.size()-1);
for(int &x:g)
cout<<x<<endl;
quicksort(s, 0, s.size()-1);
int i=0,j=0,ans=0;
while(i<g.size())
{
while(j<s.size() && s[j]<g[i]) //一定不要写反!!!(s[j]<g[i]&&j<s.size() )
{
j++;
}
if(j<s.size())
{
i++;
ans++;
j++;
}
else
break;
}
return ans;
}
};
事实证明,还是调库最香
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int i=0,j=0,ans=0;
while(i<g.size())
{
while(j<s.size() && s[j]<g[i])
{
j++;
}
if(j<s.size())
{
i++;
ans++;
j++;
}
else
break;
}
return ans;
}
};
- 不重叠的区间个数
看了答案:
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.empty()) {
return 0;
}
sort(intervals.begin(), intervals.end(), [](const auto& u, const auto& v) {
return u[1] < v[1];
});
int n = intervals.size();
int right = intervals[0][1]; //考虑如果元素个数为0怎么办
int ans = 1;
for (int i = 1; i < n; ++i) {
if (intervals[i][0] >= right) {
++ans;
right = intervals[i][1];
}
}
return n - ans;
}
};
贪心思想所谓的局部最优构成全局最优,体现在这个问题上实际就是先确定第一个元素,再去确定下一个元素。但是如何去确定第一个元素,通常需要用到排序,取最值,也就是局部最优。
4. 投飞镖刺破气球
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
if(points.empty())
return 0;
sort(points.begin(),points.end(),[](const auto& u, const auto& v) {
return (u[0] < v[0]) && (u[1] < v[1]);
//首先想到的是根据左端点值排序,没有考虑到左端点相同时还应该以右端点排序
//貌似上面这种写法并不能实现我想要的功能,return u[0] < v[0] || (u[0] == v[0] && u[1] > v[1]);
//看了一下答案,答案是直接对右端点进行排序??为何??
});
int right=points[0][1];
int ans=1;
for(int i=1;i<points.size();i++)
{
if(points[i][0]>right)
{
ans++;
right=points[i][1];
}
}
return ans;
}
};
- 根据身高重建队列
核心思想:根据身高排序,并将第i个元素放到第i+1个空格处。如果身高相等,按照k值做第二次排序。
class Solution {
public:
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(), people.end(), [](const vector<int>& u, const vector<int>& v) {
return u[0] < v[0] || (u[0] == v[0] && u[1] > v[1]);
});
int n = people.size();
vector<vector<int>> ans(n);
for (const vector<int>& person: people) {
int spaces = person[1] + 1;
for (int i = 0; i < n; ++i) {
if (ans[i].empty()) {
--spaces;
if (!spaces) {
ans[i] = person;
break;
}
}
}
}
return ans;
}
};