贪心算法之两端贪

这类题目一般是当前元素的位置既受前一个元素的影响又受后一个元素的影响。
题目一定是要确定一边之后,再确定另一边,例如比较每一个元素的左边,然后再比较右边,如果两边一起考虑一定会顾此失彼。
当确定一边后,就单独看排完序的数组,因为这时候只需考虑一边,因此容易找规律。
典型题目:
135. 分发糖果

点击查看代码
class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> candyVec(ratings.size(), 1);
        // 从前向后
        for (int i = 1; i < ratings.size(); i++) {
            if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;
        }
        // 从后向前
        for (int i = ratings.size() - 2; i >= 0; i--) {
            if (ratings[i] > ratings[i + 1] ) {
                candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);
            }
        }
        // 统计结果
        int result = 0;
        for (int i = 0; i < candyVec.size(); i++) result += candyVec[i];
        return result;
    }
};

406.根据身高重建队列

点击查看代码
class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        if (a[0] == b[0]) return a[1] < b[1];
        return a[0] > b[0];
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort (people.begin(), people.end(), cmp);
        vector<vector<int>> que;
        for (int i = 0; i < people.size(); i++) {
            int position = people[i][1];
            que.insert(que.begin() + position, people[i]);
        }
        return que;
    }
};
  1. 用最少数量的箭引爆气球
点击查看代码
class Solution {
public:
 static bool cmp(vector<int>&a,vector<int>&b){
     return a[0]<b[0];
 }
    int findMinArrowShots(vector<vector<int>>& points) {
int sz=points.size();
sort(points.begin(),points.end(),cmp);
int count=1;
for(int i=1;i<sz;i++){
    if(points[i][0]>points[i-1][1]){++count;}
    else{
        points[i][1]=min(points[i-1][1],points[i][1]);
    }
}
return count;
    }
};
posted @ 2024-01-28 10:22  yun-che  阅读(27)  评论(0)    收藏  举报