目录
题目一:分发饼干
题目描述:
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干
思路分析:(代码随想录)
利用局部最优推出全局最优
解法一:
class Solution {
// 优先考虑胃口,先喂饱大胃口
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int start = s.length - 1;
int count = 0;
for (int i = g.length - 1; i >= 0; i--) {
if(start >= 0 && g[i] <= s[start]) {
start--;
count++;
}
}
return count;
}
}
解法二:
class Solution {
// 优先考虑饼干,小饼干先喂饱小胃口
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int start = 0;
int count = 0;
for (int i = 0; i < s.length && start < g.length; i++) {
if (s[i] >= g[start]) {
start++;
count++;
}
}
return count;
}
}
题目二:摆动序列
题目描述:
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。
思路分析:(代码随想录)
局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。
整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列
代码:
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 = 1; i < nums.length; i++) {
//得到当前差值
curDiff = nums[i] - nums[i - 1];
//如果当前差值和上一个差值为一正一负
//等于0的情况表示初始时的preDiff
if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) {
count++;
preDiff = curDiff;
}
}
return count;
}
}
题目三:最大子序和
题目描述:
给你一个整数数组 nums
,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分
思路分析:(视频指路)
计算出每一个子数组的和,将其视为一个区间内的和,并把每次最大值保存与下一个元素进行比较,二者之中更大的即为全局最大值。
解法一:
class Solution {
public int maxSubArray(int[] nums) {
int maxSumEndAtHere = nums[0]; // 前一个区间可取到的最大和
int max = nums[0]; // 全局最大和
for (int i = 1; i < nums.length; i++) {
maxSumEndAtHere = Math.max(maxSumEndAtHere + nums[i], nums[i]);
max = Math.max(max, maxSumEndAtHere);
}
return max;
}
}
解法二:
class Solution {
public int maxSubArray(int[] nums) {
if (nums.length == 1){
return nums[0];
}
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;
}
}