理论基础
贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。
不用花心思去研究其规律, 没有思路就立刻看题解。
基本贪心的题目 有两个极端,要不就是特简单,要不就是死活想不出来。
学完贪心之后再去看动态规划,就会了解贪心和动规的区别
分发饼干
思路:
从代码中可以看出我用了一个 index 来控制饼干数组的遍历,遍历饼干并没有再起一个 for 循环,而是采用自减的方式,这也是常用的技巧。
有的同学看到要遍历两个数组,就想到用两个 for 循环,那样逻辑其实就复杂了。
代码:
class Solution {
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int start = s.length-1;//饼干的下标
int res=0;
for(int i=g.length-1;i>=0;i--){// 循环判断
if(start>=0&&s[start]>=g[i]){
res++;
start--;
}
}
return res;
}
}
摆动序列
思路一 贪心算法:
代码:
class Solution {
public int wiggleMaxLength(int[] nums) {
if (nums.length <= 1) {
return nums.length;
}
//当前差值
int curDiff = 0;
//上一个差值
int preDiff = 0;
int count = 1;//默认最右边是峰值
for (int i = 0; i < nums.length-1; i++) {
//得到当前差值
curDiff = nums[i+1] - nums[i];
//如果当前差值和上一个差值为一正一负
//等于0的情况表示初始时的preDiff
if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) {
count++;
preDiff = curDiff;
}
}
return count;
}
}
思路二:动态规划(想不清楚)
代码:
class Solution {
public int wiggleMaxLength(int[] nums) {
// 0 i 作为波峰的最大长度
// 1 i 作为波谷的最大长度
int dp[][] = new int[nums.length][2];
dp[0][0] = dp[0][1] = 1;
for (int i = 1; i < nums.length; i++){
//i 自己可以成为波峰或者波谷
dp[i][0] = dp[i][1] = 1;
for (int j = 0; j < i; j++){
if (nums[j] > nums[i]){
// i 是波谷
dp[i][1] = Math.max(dp[i][1], dp[j][0] + 1);
}
if (nums[j] < nums[i]){
// i 是波峰
dp[i][0] = Math.max(dp[i][0], dp[j][1] + 1);
}
}
}
return Math.max(dp[nums.length - 1][0], dp[nums.length - 1][1]);
}
最大子序和
思路:
代码:
class Solution {
public int maxSubArray(int[] nums) {
int sum = Integer.MIN_VALUE;
int count = 0;
for(int i=0;i<nums.length;i++){
count+=nums[i];//?来判断是否结果是负数
sum=Math.max(sum,count);// 取区间累计的最大值(相当于不断确定最大子序终止位置)
if(count<0){//重置起始位置
count=0;
}
}
return sum;
}
}