优点:简单,高效,省去了为了找最优解可能需要穷举操作,通常作为其它算法的辅助算法来使用;
缺点:不从总体上考虑其它可能情况,每次选取局部最优解,不再进行回溯处理,所以很少情况下得到最优解。
每一步都选取当前状态下最好的选择(局部最优)。(整体不一定是最优解)
助记:贪心即比较贪婪只注重"眼前利益"不能长远考虑
正是因为原问题太复杂无法直接得到全局最优解,所以也无法判定贪心算法得到的结果是否逼近全局最优解,只要最终得到的结果在接受范围内即可
例题案例
注:以下两个案例均不能得到最优解,只能得到近似最优解,案例只是解释思想
1.找零钱问题
假设你开了间小店,不能电子支付,钱柜里的货币只有 25 分、10 分、5 分和 1 分四种硬币,如果你是售货员且要找给客户 41 分钱的硬币,如何安排才能找给客人的钱既正确且硬币的个数又最少?
思路:如果用贪心算法求解
要找给顾客41分且硬币数最少,那么大数值的硬币数越多越好。先用一个25分的,41-25=16。
然后根据局部最优当找零为16时从25,10,5,1中选一个,我们可以选10,16-10=6
找零数为6时从25,10,5,1中选一个,我们可以选5,6-5=1,以此类推
我们可以看到当做出一个选择后,然后相当于以现在的状态为起始状态,再次做出选择
*int* money=41;
int num_25=0,num_10=0,num_5=0,num_1=0;
//不断尝试每一种硬币
while(money>=25) { num_25++; money -=25; }
while(money>=10) { num_10++; money -=10; }
while(money>=5) { num_5++; money -=5; }
while(money>=1) { num_1++; money -=1; }
//输出结果
cout<< "25分硬币数:"<<num_25<<endl;
cout<< "10分硬币数:"<<num_10<<endl;
cout<< "5分硬币数:"<<num_5<<endl;
cout<< "1分硬币数:"<<num_1<<endl;
/*25分硬币数:1
10分硬币数:1
5分硬币数:1
1分硬币数:1*/
2.01背包问题
有一个背包,最多能承载重量为 C=150的物品,现在有7个物品(物品不能分割成任意大小),编号为 1~7。
重量分别是 wi=[35,30,60,50,40,10,25],价值分别是 pi=[10,40,30,50,35,40,30]。
现在从这 7 个物品中选择一个或多个装入背包,要求在物品总重量不超过 C 的前提下,所装入的物品总价值最高。
思路:若用贪心算法,有3种策略
- 价值主导选择,每次都选价值最高的物品放进背包;
- 重量主导选择,每次都选择重量最轻的物品放进背包;
- 价值密度主导选择,每次选择都选价值/重量最高的(性价比最高的)物品放进背包。
策略1:每次优先选价值最高的
解:按照价值排序则放入背包的编号依次为4、2、6、5。
其价值为50+40+40+35=165,其重量为50+30+10+40=130
策略2:每次优先选重量最轻的
解:按照重量最轻则放入的编号依次为6、7、2、1、5
其价值为40+30+40+10+35=155,其重量为10+25+30+35+40=140
策略3:每次优先选价值/重量最大的
解:这7件物品的价值密度分别为0.286、1.333、0.5、1.0、0.875、4.0、1.2
所以放入的编号依次为6、2、7、4、1
其价值为40+40+30+50+10=170,其重量为10+30+25+50+35=150
LeetCode习题
🚩1.题目1221分割平衡字符串问题
在一个 平衡字符串 中,‘L’ 和 ‘R’ 字符的数量是相同的。给你一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串。
注意:分割得到的每个字符串都必须是平衡字符串。返回可以通过分割得到的平衡字符串的最大数量 。
输入:s = “RLRRLLRLRL”
输出:4
解释:s 可以分割为 “RL”、“RRLL”、“RL”、“RL” ,每个子字符串中都包含相同数量的 ‘L’ 和 ‘R’ 。
解:用变量balance(初始为0)记录扫描到的L和R的数目,遇到L则balance+1否则减1当其为0的时候说明当前找到了平衡子串
上一次划分后balance=0,剩下的平衡子串接着用上述思想(贪心思想)
int balancedStringSplit(string s) {
int len=s.length();
int balance=0,result=0;
for (int i = 0; i < len; i++)
{
if(s[i]=='L') balance++;
if(s[i]=='R') balance--;
if(balance==0) result++;
}
return result;
}