持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天
贪心:希望通过局部最优解,或得全局最优解。
贪心算法不能回退,所以在某些场景下,得不到最优解,如零钱兑换。
下面是初次理解该算法时,比较好入门的几个题。
贪心
力扣860-柠檬水找零
贪心算法没有固定公式,有时候感觉就是这么个逻辑。
思路分析: 按照付钱顺序
- 如果接收到的是5,那么5计数加1
- 如果接收到的是10,那么要找零5元,所以当前5元面额小于1张时,则返回false;可以找零时,5元找零计数减1,10元计数加1。
- 如果接收到的是20,20是最大面额,不参数找零,所以不进行计数。20分为两种情况,可以找零一个10元,一个5元;也可以找零3个5元,然后分别对其计数。 具体代码实现:
/**
* @param {number[]} bills
* @return {boolean}
*/
var lemonadeChange = function(bills) {
let fiveNum = 0;
let tenNum = 0;
for(let i = 0; i < bills.length; i++) {
let bill = bills[i];
if (bill === 5) {
fiveNum++
} else if (bill === 10) {
if (fiveNum < 1) {
return false
}
fiveNum--
tenNum++
} else {
// 20情况
if (fiveNum >=1 && tenNum >= 1) {
fiveNum--
tenNum--
} else if (fiveNum >= 3) {
fiveNum = fiveNum - 3
} else {
return false
}
}
}
return true
};
力扣55-跳跃游戏
解题思路:
定义一个临时变量cover,代表当前位置i可以跳跃的最远距离。cover和数组的当前元素nums[i]取最大的值(nums[i]需要加上当前已经跳跃的步数i)。
当cover已经可以跳出,那么则返回true。
- 需要注意的是,判断条件为什么是cover+1:因为cover为0的时候,本身就占了一个占位,长度为1,而不直接定义cover为1,是为了for循环中比较好计算。
/**
* @param {number[]} nums
* @return {boolean}
*/
var canJump = function(nums) {
let cover = 0;
for (let i = 0; i <= cover; i++) {
cover = Math.max(cover, nums[i] + i)
// cover >= nums.length的话,[2,0,0]则不过,因为未计算cover的占位长度1
if (cover + 1 >= nums.length) {
return true;
}
}
return false;
};
力扣455-分发饼干
解题思路:
先进行从大到小排序, 如果饼干能满足孩子的胃口,则计数吃掉一个饼干,最后统计吃掉了几块饼干。
饼干可能比孩子少,所以防止undedined出现,进行下判断
/**
* @param {number[]} g
* @param {number[]} s
* @return {number}
*/
var findContentChildren = function(g, s) {
g.sort((a,b) => b - a)
s.sort((a,b) => b - a)
let index = 0;
for(let i = 0; i < g.length; i++) {
if (s[index] && s[index] >= g[i]) {
index++
}
}
return index;
};