代码随想录算法训练营Day27
贪心算法
通过局部最优,推出整体最优。
刷题或者面试的时候,手动模拟一下感觉可以局部最优推出整体最优,而且想不到反例,那么就试一试贪心,贪心有时是常识性的,所以会认为本就应该这样做
分发饼干
class Solution {
public int findContentChildren(int[] g, int[] s) {
//饼干大于等于胃口,满足
//排序之后双指针
Arrays.sort(g);
Arrays.sort(s);
int i = 0;
int j = 0;
while(j<s.length){
if(i==g.length){
break;
}
if(s[j] >= g[i]){
i++;
j++;
}else{
j++;
}
}
return i;
}
}
摆动序列
三种情况:上下有平坡,首尾元素,单调有平坡
class Solution {
public int wiggleMaxLength(int[] nums) {
//摆动序列:相邻元素的差值正负交替,仅有一个元素或者含两个不等元素的序列也视作摆动序列
//给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度
if(nums.length==1){
return 1;
}
int result = 0;
int prediff = 0;
int curdiff = 0;
for (int i = 0; i < nums.length - 1; i++) {//这里不用遍历最后一个,因为最右端肯定会+1
curdiff = nums[i+1] - nums[i];
if((prediff>=0&&curdiff<0)||(prediff<=0&&curdiff>0)){
result++;
prediff = curdiff;//只有prediff和curdiff方向不同时,才会改变prediff的值,这里解决的是单调有平坡的情况
}
}
result++;
return result;
}
}
最大子数组和
- 用前缀和数组,结合“最大前缀和减去之前的最小前缀和”来求最大子数组和,是一种经典且有效的方法
- 但直接用“最大值减去最小值”且不考虑它们的顺序关系,是不正确的。
- 实际实现时,通常用一个变量跟踪当前最小前缀和,遍历前缀和数组更新最大差值,即最大子数组和。
- 暴力解法,会超时
class Solution {
public int maxSubArray(int[] nums) {
int max = Integer.MIN_VALUE;
for(int i = 0;i<nums.length;i++){
int sum = 0;
for(int j = i;j<nums.length;j++){
sum+=nums[j];
max = max>sum?max:sum;
}
}
return max;
}
}
- 错误解法,想当然了
class Solution {
public int maxSubArray(int[] nums) {
if(nums.length>1){
int[] sum = new int[nums.length-1];
for(int i = 1,j = 0;i<nums.length;i++){
if(j==0){
sum[j++] = nums[i]+nums[i-1];
}else{
sum[j++] = nums[i] + sum[j-1];
}
}
return getMax(sum) - getMin(sum);
}else{
return nums[0];
}
}
- 贪心算法
class Solution {
public int maxSubArray(int[] nums) {
int cursum = 0;
int result = Integer.MIN_VALUE;//这里的初始值
for(int i = 0;i<nums.length;i++){
cursum+=nums[i];
result = Math.max(cursum, result);//这里取值的顺序
if(cursum < 0){
cursum = 0;
}
}
return result;
}
}

浙公网安备 33010602011771号