概念理解
贪心算法(英语:greedy algorithm),又称贪婪算法,是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。-- 维基百科
贪心算法
是算法设计中的一种方法。期盼通过每个阶段的局部最优
选择,从而达到全局最优,但是结果并不一定是最优的
。常见的反面例子如:零钱兑换问题。
使用场景
二叉树
等算法题,解题经常用到贪心算法。
详细可参考以下例题讲解,通过刷以下题集以加深和巩固对于模拟算法的理解。
例题讲解
题目: 分糖果问题
描述
一群孩子做游戏,现在请你根据游戏得分来发糖果,要求如下:
- 每个孩子不管得分多少,起码分到一个糖果。
- 任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果。(若相同则无此限制) 给定一个数组 arr 代表得分数组,请返回最少需要多少糖果。
要求: 时间复杂度为 O(n),空间复杂度为 O(n)
示例1
输入:
[1, 1, 2]
返回值:
4
说明:
最优分配方案为 1, 1, 2
示例2
输入:
[1, 1, 1]
返回值:
3
说明:
最优分配方案是 1, 1, 1
题解:
/**
* 解法:贪心
* 思路:
* 要想分出最少的糖果,利用贪心思想,肯定是相邻位置没有增加的情况下大家都分到1,
* 相邻位置有增加的情况下,分到糖果数加1就好。什么情况下会增加糖果,相邻位置有得
* 分差异,可能是递增可能是递减,如果是递增的话,糖果依次加1,如果是递减糖果依次减1?
* 这不符合最小,必须从1开始加才是最小,那我们可以反向加1.
* 时间复杂度:O(n),单独遍历两次.
* 空间复杂度:O(n)。记录每个位置糖果数的辅助数组.
*/
export function candy(arr: number[]): number {
const len = arr.length
if (len <= 1) return len
let nums: number[] = []
for (let i = 0; i < len; i++) {
nums[i] = 1
}
for (let i = 1; i < len; i++) {
if (arr[i] > arr[i - 1]) { // 如果右边在递增,每次增加一个
nums[i] = nums[i - 1] + 1
}
}
let res = nums[len - 1] // 记录总糖果数
for (let i = len - 2; i >= 0; i--) {
if (arr[i] > arr[i + 1] && nums[i] <= nums[i + 1]) { // 如果左边更大但是糖果树更小
nums[i] = nums[i + 1] + 1
}
res += nums[i] // 累加和
}
return res
}
题集&题解
序号 | 题目 | 题解 | 难度 |
---|---|---|---|
1 | 分糖果问题 | 题解 | medium |
2 | 主持人调度(二) | 题解 | medium |
相关文章
- 前端算法入门一:刷算法题常用的JS基础扫盲
- 前端算法入门二:时间空间复杂度&8大数据结构的JS实现
- 前端算法入门三:5大排序算法&2大搜索&4大算法思想
- 前端面试算法高频100题(附答案,分析思路,一题多解)
您的点赞和评论是我持续更新的动力,感谢关注。