【算法笔记】汇总——贪心篇
本篇内容的主旨在于总结LeetCode
中常见的贪心题涉及的基本内容,并对此做出一定的总结与归纳,算是笔者心路历程的一些许感悟。
首先,我们将贪心题按难易程度划分为如下情况:
贪心简单题
以下三道题目就是简单题,大家会发现贪心感觉就是常识。是的,如下三道题目,就是靠常识,分析出局部最优是什么,全局最优是什么,贪心贪的也就有理有据!
贪心算法:分发饼干
贪心算法:K次取反后最大化的数组和
贪心算法:柠檬水找零
贪心中等题
贪心中等题,靠常识可能就有点想不出来了。开始初现贪心算法的难度与巧妙之处。
贪心算法:摆动序列
贪心算法:单调递增的数字
【笔记】:本题型涉及贪心算法的应用,题干的问题很容易理解,即求解
单调数字
,且保证<=N
的最大的整数。固定思维考虑模拟,但存在TTL,不能采用。并且由题意可知,需要将输入的整数转化为字符数组进行考虑,需满足下面条件时进行更新:即当且仅当str[i-1]>str[i]时,str[i-1]--,str[i]=9
。
【注意】:考虑到从右向左遍历过程中,存在先单调后不单调的情况,需要记录最后满足上述条件的索引,来进行更新。
public int monotoneIncreasingDigits(int n) {
if (n == 0) {
return 0;
}
char[] arr = Integer.toString(n).toCharArray();
int start = Integer.MAX_VALUE;
for (int i = arr.length - 1; i >= 1; i--) {
if (arr[i - 1] > arr[i]) {
start = i;
arr[i - 1]--;
}
}
StringBuilder res = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == '0' && i == 0) {
continue;
}
if (i >= start) {
res.append('9');
} else {
res.append(arr[i]);
}
}
return Integer.parseInt(res.toString());
}
贪心解决股票问题
大家都知道股票系列问题是动规的专长,其实用贪心也可以解决,而且还不止就这两道题目,但这两道比较典型,我就拿来单独说一说
贪心算法:买卖股票的最佳时机II
贪心算法:买卖股票的最佳时机含手续费
两个维度权衡问题
在出现两个维度相互影响的情况时,两边一起考虑一定会顾此失彼,要先确定一个维度,再确定另一个一个维度。
贪心算法:分发糖果
【笔记】:本题的核心在于对贪心算法的使用,需要对评分数组做从左到右何从右到左的两次贪心比较,即:第一次从左到右,得出右边评分比左边评分大的情况下,糖果的分配情况;第二次从右到左,在上述糖果分配的基础上,得出左边评分比右边评分大的情况。
综合上述贪心得到的结果,计算总量,即可得到分配的最少的糖果数目
public int candy(int[] ratings) {
int n = ratings.length;
int[] candyCnt = new int[n];
Arrays.fill(candy