代码随想录算法Day31 | 455.分发饼干 ,376. 摆动序列 ,53. 最大子序和

455.分发饼干

题目链接:455. 分发饼干 - 力扣(LeetCode)

思路

这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。

也可以换一个思路,小饼干先喂饱小胃口。

代码

 1 class Solution {
 2     // 思路1:优先考虑饼干,小饼干先喂饱小胃口
 3     public int findContentChildren(int[] g, int[] s) {
 4         Arrays.sort(g);
 5         Arrays.sort(s);
 6         int start = 0;
 7         int count = 0;
 8         for (int i = 0; i < s.length && start < g.length; i++) {
 9             if (s[i] >= g[start]) {
10                 start++;
11                 count++;
12             }
13         }
14         return count;
15     }
16 }
 1 class Solution {
 2     // 思路2:优先考虑胃口,先喂饱大胃口
 3     public int findContentChildren(int[] g, int[] s) {
 4         Arrays.sort(g);
 5         Arrays.sort(s);
 6         int count = 0;
 7         int start = s.length - 1;
 8         // 遍历胃口
 9         for (int index = g.length - 1; index >= 0; index--) {
10             if(start >= 0 && g[index] <= s[start]) {
11                 start--;
12                 count++;
13             }
14         }
15         return count;
16     }
17 }

 

376. 摆动序列

题目链接:376. 摆动序列 - 力扣(LeetCode)

思路

 

首先可以将题目给的数据画出如上的波峰图,根据图中可知:

局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。

整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。

在实际操作可以设置一个遍历记录峰值数量就可以了。

 当用这思路解决该问题时要注意三个问题。

  • 当仅有两个数字,当两个数字不相等时,是2个峰
  • 当仅有一个数字时,是1个峰
  • 当有N个数字,但是这N个数字值都相同时,也算1个峰

代码

 1 class Solution {
 2     public int wiggleMaxLength(int[] nums) {
 3         if (nums.length <= 1) {
 4             return nums.length;
 5         }
 6         //当前差值
 7         int curDiff = 0;
 8         //上一个差值
 9         int preDiff = 0;
10         int count = 1;
11         for (int i = 1; i < nums.length; i++) {
12             //得到当前差值
13             curDiff = nums[i] - nums[i - 1];
14             //如果当前差值和上一个差值为一正一负
15             //等于0的情况表示初始时的preDiff
16             if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) {
17                 count++;
18                 preDiff = curDiff;
19             }
20         }
21         return count;
22     }
23 }
 1 // DP
 2 class Solution {
 3     public int wiggleMaxLength(int[] nums) {
 4         // 0 i 作为波峰的最大长度
 5         // 1 i 作为波谷的最大长度
 6         int dp[][] = new int[nums.length][2];
 7 
 8         dp[0][0] = dp[0][1] = 1;
 9         for (int i = 1; i < nums.length; i++){
10             //i 自己可以成为波峰或者波谷
11             dp[i][0] = dp[i][1] = 1;
12 
13             for (int j = 0; j < i; j++){
14                 if (nums[j] > nums[i]){
15                     // i 是波谷
16                     dp[i][1] = Math.max(dp[i][1], dp[j][0] + 1);
17                 }
18                 if (nums[j] < nums[i]){
19                     // i 是波峰
20                     dp[i][0] = Math.max(dp[i][0], dp[j][1] + 1);
21                 }
22             }
23         }
24 
25         return Math.max(dp[nums.length - 1][0], dp[nums.length - 1][1]);
26     }
27 }

 

53. 最大子序和

题目链接:53. 最大子数组和 - 力扣(LeetCode)

思路

暴力解法的思路,第一层for 就是设置起始位置,第二层for循环遍历数组寻找最大值。

而贪心的方法,从第一个数开始累加,如果当前和已经为负,那么加上下一个数,一定会使下一个数变小。所以出现这种情况时,直接舍弃这个数,从下一个数开始重新计算。

详细如图

代码

 1 class Solution {
 2     public int maxSubArray(int[] nums) {
 3         if (nums.length == 1){
 4             return nums[0];
 5         }
 6         int sum = Integer.MIN_VALUE;
 7         int count = 0;
 8         for (int i = 0; i < nums.length; i++){
 9             count += nums[i];
10             sum = Math.max(sum, count); // 取区间累计的最大值(相当于不断确定最大子序终止位置)
11             if (count <= 0){
12                 count = 0; // 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
13             }
14         }
15        return sum;
16     }
17 }
 1 // DP 方法
 2 class Solution {
 3     public int maxSubArray(int[] nums) {
 4         int ans = Integer.MIN_VALUE;
 5         int[] dp = new int[nums.length];
 6         dp[0] = nums[0];
 7         ans = dp[0];
 8 
 9         for (int i = 1; i < nums.length; i++){
10             dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);
11             ans = Math.max(dp[i], ans);
12         }
13 
14         return ans;
15     }
16 }

 

posted @ 2023-03-04 00:19  颜欢兮  阅读(25)  评论(0)    收藏  举报