Greedy Algorithm 贪心

138 阅读3分钟

greedy algorithm is any algorithm that follows the problem-solving heuristic of making the locally optimal choice at each stage.In many problems, a greedy strategy does not produce an optimal solution, but a greedy heuristic can yield locally optimal solutions that approximate a globally optimal solution in a reasonable amount of time.

常见问题与算法

 贪心算法典型的用来解决的问题,包括活动选择问题分数背包问题
基于贪心方法设计的算法,包括 Huffman编码,单源最短路径的Dijsktra算法,最小生成树(minimum-spanning-tree)算法(Kruskal算法和Prim算法)。

动态规划与贪心算法的区别和联系

After every stage, dynamic programming makes decisions based on all the decisions made in the previous stage and may reconsider the previous stage's algorithmic path to the solution.

  1. 动态规划与贪心算法求解的问题都必须具备最优子结构性质。
  2. 贪心算法本质上是对动态规划的优化,对每个用贪心算法求解的问题,几乎也存在一个动态规划的解法。
  3. 动态规划方法中,每个步骤要进行一次选择,但选择通常依赖于子问题的解,因此通常使用自底向上的方法,先求解较小子问题,再根据子问题的解做出选择。而贪心算法在进行第一次选择之前不求解任何子问题,通常采用自顶向下的方法,进行一次又一次选择,将给定问题实例变小。

参考

最小生成树: kruskal算法 prim算法

贪心例题

基础

题目来源

455. Assign Cookies

这道题在最新Amazon2024年的OA中有类似题。链接 Amazon OA很喜欢出贪心题

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(), g.end());
        sort(s.begin(), s.end());
        int count = 0, start_g = 0, start_s = 0;
        while(start_g < g.size() && start_s < s.size()){
            if(g[start_g] <= s[start_s]) {
                count++;
                start_g++, start_s++;
            } else{
                start_s++;
            }
        }
        return count;
    }
};

注意细节,难度不高,用直觉就能做出来。链接

55. 跳跃游戏 55. Jump Game

class Solution {
public:
    bool canJump(vector<int>& nums) {
        vector<int> new_arr(nums.size(),0);
        new_arr[0] = 1;
        for(int i = 0; i < nums.size(); i++){
            if(new_arr[i] == 1)
            {
                for(int j = 1; j <= nums[i]; j++){
                    if(i+j < nums.size() && new_arr[i+j] == 0)
                     new_arr[i+j] = 1; 
                     if(i+j == nums.size()-1) return true;
                }
            }
        }
        return new_arr[nums.size()-1] == 1;
    }
};

自己做出来的!没看提示!用的数学直觉!yeah!

122. 买卖股票的最佳时机 II

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int max_profit = 0;
        for(int i = 0; i < prices.size() - 1; i++){
            if(prices[i+1] > prices[i]){
                max_profit += prices[i+1] - prices[i];
            }
        }
        return max_profit;
    }
};

之前是五月份做过一次,这次很流畅就做出来了,原来做过的题真的会有记忆。开心。

明天复习 我怎么一好好学习接下来就不行了。我痛哭妈的。

45. 跳跃游戏 II 鲤鱼大佬的答案

class Solution {
public:
    int jump(vector<int>& nums) {
        int maxPos = 0;  // 当前能走到的最远位置
        int end = 0;  // 上次跳跃可达范围右边界
        int ans = 0;
        for (int i = 0; i < nums.size() - 1; i++) {
            maxPos = max(maxPos, nums[i] + i);
            // 已到达上次跳跃可达范围右边界,需要再次起跳
            if (i == end) {
                end = maxPos;
                ans++;
            }
        }
        return ans;
    }
};

135. 分发糖果 135. Candy

class Solution {
public:
    int candy(vector<int>& ratings) {
       int n = ratings.size();
       vector<int> left(n), right(n);
       for(int i = 1; i < n; i++){
           if(ratings[i]>ratings[i-1]) left[i] = left[i-1]+1;
       }
       for(int i = n-2; i >= 0; i--){
           if(ratings[i] > ratings[i+1]) right[i] = right[i+1]+1;
       }
       int ans = 0;
       for(int i = 0; i < n; i++){
           ans += max(right[i], left[i])+1;
       }
       return ans;
    }
};

做了这些题,觉得贪心基础题怎么更像是在找规律。这道题和股票题好像。其实做到这里觉得自己并没有完全的懂得贪心的意义,只是在找规律。老师上课的时候再问问