这是贪心算法第一天:
首先了解了贪心算法,贪心算法是选择每一部局部最优以达到全局最优解,贪心有四个步骤 1)
455.分发饼干
题目链接:. - 力扣(LeetCode)
思路:将两个数组,胃口值 g和尺寸s进行排序,用双指针法,如果胃口值小于且等于尺寸值,则次数+ 1,然后移动两个指针的位置,如果不满足条件,则只移动尺寸值的指针,代码实现如下:
var findContentChildren = function (g, s) {
g.sort((a, b) => a - b);
s.sort((a, b) => a - b);
let left = 0, right = 0;
let count = 0
while (left < g.length && right < s.length) {
if (g[left] <= s[right]) {
count = count + 1;
left = left + 1;
right = right + 1
} else {
right = right + 1
}
}
return count
};
卡哥思路是用局部最优去推导出全局最优,这里的局部最优是用最大的尺寸去满足最大的胃口,我感觉和双指针的思路其实类似;
var findContentChildren = function (g, s) {
g.sort((a, b) => a - b)
s.sort((a, b) => a - b)
let index = s.length - 1
let result = 0
for (let i = g.length - 1; i >= 0; i = i - 1) {
if (s[index] >= g[i] && index >=0) {
result = result + 1
index = index - 1
}
}
return result
};
376. 摆动序列
题目链接:. - 力扣(LeetCode)
这道题分析了一下还是比较懵的,既要求差值为摆动序列的,而且这个摆动序列还可以是去掉一些值后形成的子序列的个数;看完卡哥的讲解整理了一下思路:
1) 首先如果要形成摆动序列,那么就会存在峰值的情况也就是存在 preDiff >0 且 curDiff < 0 以及 preDiff < 0 且 curDiff > 0的情况;在做判断之后,去更新 preDiff为 curDiff的情况
2) 但是这样的话,其实是忽略了首尾的情况,那么假设首尾还有一个元素,是和首尾元素相同的元素,那么其实应该是preDiff >=0 且 curDiff < 0 以及 preDiff <= 0 且 curDiff > 0的情况下,去对 result做增加
3)但是这样并没有通过所有测试用例,因为存在中间是平坡,且单调递增的序列,这样的其实如果也用 preDiff <= 0 且 curDiff > 0这个条件去判断的话,是会多增加一条,因为 preDiff是实时更新的,在中间是平坡时,preDiff 又更新为 0,那么又满足了preDiff <= 0 且 curDiff > 0这个条件,所以出现了多加一次的情况;那其实应该在动态变化记录 result的时候,才去更新 preDiff
实现代码:
var wiggleMaxLength = function (nums) {
let preDiff = 0, curDiff = 0;
let result = 0
for (let i = 0; i < nums.length - 1; i = i + 1) {
curDiff = nums[i + 1] - nums[i]
if ((preDiff >= 0 && curDiff < 0) || (preDiff <= 0 && curDiff > 0)) {
result = result + 1
preDiff = curDiff
}
}
return result + 1 // 默认序列最后有一个序列
};
贪心算法:通过找到局部峰值来找到这个数组的最大峰值
53. 最大子序和
题目链接:. - 力扣(LeetCode)
思路:
暴力解法:通过遍历来对比出最大的和;贪心算法没有什么思路,总结了一下卡哥的思路:
这里局部最优解的定义是,如果当前累加和是负数的情况下遇到了正数,那么直接抛弃前面的累加和,从这个正数开始重新累加;那么实际上的实现思路是,通过 count 来累加,然后将 count 的最大值赋给 result,如果遇到 count 为负数的情况,直接将 count 赋值为 0,因为之前的和都为负数,后面为正数的话,还不如直接从正数开始计算,如果后面是负数的话,继续求和也是会将和减少
/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function (nums) {
let result = Number.MIN_VALUE, count = 0;
for (let i = 0; i < nums.length; i = i + 1) {
count = count + nums[i]
result = Math.max(result, count) // 如果全是负数,这里已经求出来结果了
if(count < 0) {
count = 0
}
}
return result
};