代码随想录算法训练营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;  
    }  
}

最大子数组和

  • 用前缀和数组,结合“最大前缀和减去之前的最小前缀和”来求最大子数组和,是一种经典且有效的方法
  • 但直接用“最大值减去最小值”且不考虑它们的顺序关系,是不正确的。
  • 实际实现时,通常用一个变量跟踪当前最小前缀和,遍历前缀和数组更新最大差值,即最大子数组和。
  1. 暴力解法,会超时
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;  
    }  
}
  1. 错误解法,想当然了
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];  
        }  
    }  

  1. 贪心算法
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;  
    }  
}
posted @ 2025-04-22 08:46  Anson_502  阅读(6)  评论(0)    收藏  举报