A 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.
- 动态规划与贪心算法求解的问题都必须具备最优子结构性质。
- 贪心算法本质上是对动态规划的优化,对每个用贪心算法求解的问题,几乎也存在一个动态规划的解法。
- 动态规划方法中,每个步骤要进行一次选择,但选择通常依赖于子问题的解,因此通常使用自底向上的方法,先求解较小子问题,再根据子问题的解做出选择。而贪心算法在进行第一次选择之前不求解任何子问题,通常采用自顶向下的方法,进行一次又一次选择,将给定问题实例变小。
贪心例题
基础
这道题在最新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;
}
};
注意细节,难度不高,用直觉就能做出来。链接
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!
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;
}
};
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;
}
};
做了这些题,觉得贪心基础题怎么更像是在找规律。这道题和股票题好像。其实做到这里觉得自己并没有完全的懂得贪心的意义,只是在找规律。老师上课的时候再问问