双向权衡问题相当于既要又要,依然是贪心的思路,先完成一个要求,在完成另一个要求。
也就是说用两个局部最优(一般第二个局部最优是在第一个的基础上进行),去完成全局最优。
135. 分发糖果
n
个孩子站成一排。给你一个整数数组 ratings
表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到
1
个糖果。 - 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
思路:
先确定右边评分大于左边的情况(也就是从前向后遍历)
局部最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果
再确定左孩子大于右孩子的情况(从后向前遍历)
局部最优:相邻的孩子中,评分高的左孩子获得比右边孩子更多的糖果
在第一个局部最优的基础上(两者结合):
vec_candy[i]=max(vec_candy[i],vec_candy[i+1]+1);//前者是从前向后遍历的结果,后者是当前结果
代码如下:
class Solution { public: int candy(vector<int>& ratings) { vector<int> vec_candy(ratings.size(),1); for(int i=1;i<ratings.size();i++){ if(ratings[i]>ratings[i-1]){//第一贪 vec_candy[i]=vec_candy[i-1]+1; } } for(int i=ratings.size()-2;i>=0;i--){ if(ratings[i]>ratings[i+1]){//第二贪 vec_candy[i]=max(vec_candy[i],vec_candy[i+1]+1); } } int res=0; for(int x:vec_candy){ res+=x; } return res; } };
假设有打乱顺序的一群人站成一个队列,数组 people
表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki]
表示第 i
个人的身高为 hi
,前面 正好 有 ki
个身高大于或等于 hi
的人。
请你重新构造并返回输入数组 people
所表示的队列。返回的队列应该格式化为数组 queue
,其中 queue[j] = [hj, kj]
是队列中第 j
个人的属性(queue[0]
是排在队列前面的人)。
思路:
先按照身高来排序,从大到小排。
然后从前往后遍历,根据每人的k值插入到对应的位置。
代码如下:
class Solution { public: vector<vector<int>> reconstructQueue(vector<vector<int>>& people) { // 先按身高降序排列,如果身高相同,按k值升序排列 sort(people.begin(), people.end(), [](const vector<int>& a, const vector<int>& b) { return a[0] > b[0] || (a[0] == b[0] && a[1] < b[1]);//注意这里当相等时k大的排在后面 }); vector<vector<int>> result; // 根据每个人的 k 值插入到对应的位置 for (const auto& person : people) { result.insert(result.begin() + person[1], person); } return result; } };
暂无评论