贪心算法
思想:
在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素。
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。运用贪心策略在每一次转化时都取得了最优解。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。贪心算法的每一次操作都对结果产生直接影响。贪心算法对每个子问题的解决方案都做出选择,不能回退。
贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解。 每一步只考虑一个数据,他的选取应该满足局部优化的条件。若下一个数据和部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止
过程:
-
建立数学模型来描述问题;
-
把求解的问题分成若干个子问题;
-
对每一子问题求解,得到子问题的局部最优解;
-
把子问题的局部最优解合成原来解问题的一个解
问题比较复杂,无法得出全局最优解时,尝试将问题拆分成多个小问题(分治),求小问题的最优解,通过小问题的最优解的出整个问题的最优解。
算法缺陷
不能保证求得的最后解是最佳的
不能用来求最大值或最小值的问题
只能求满足某些约束条件的可行解的范围
例题解析:
在一个「平衡字符串」中,‘L’ 和 ‘R’ 字符的数量是相同的。
给出一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串。
返回可以通过分割得到的平衡字符串的最大数量**注意:**分割得到的每个字符串都必须是平衡字符串,且分割得到的平衡字符串是原平衡字符串的连续子串。
问题:分割的子串是平衡串,子串必须连续,数量最多
贪心策略:出现平衡就分割
class Solution {
public int balancedStringSplit(String s) {
int count = 0;
int len = s.length();
int i = 0;
while(i<len){
int countL = 0;
int countR = 0;
while(i<len){
if(i<len && s.charAt(i++)=='L')
countL++;
if(i<len && s.charAt(i++)=='R')
countR++;
if(countL == countR){
count++;
break;
}
}
}
return count;
}
}
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
问题:获取最大利润?即低卖高买
贪心策略:今天价格高于昨天就卖出
class Solution {
public int maxProfit(int[] prices) {
//贪心算法:在升序区间最低点买入,高点卖出/第二天比第一天高就卖出
int ret = 0;
for(int i=1;i<prices.length;i++){
if(prices[i-1]<prices[i]){
ret += prices[i]-prices[i-1];
}
}
return ret;
}
}