LeetCode 455. 分发饼干
题目链接:455. 分发饼干
思路:简单的想一下,是不是每次只需要将尽量小且能满足孩子的饼干给到相应胃口的孩子,那就能做到满足尽可能多的孩子(不浪费大饼干的资源给胃口小的孩子)。
go版本:
func findContentChildren(g []int, s []int) int {
sort.Ints(g)
sort.Ints(s)
res := 0
for i:=0; res<len(g) && i<len(s); i++ {
if s[i] >= g[res] {
res++
}
}
return res
}
时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1)
LeetCode 376. 摆动序列
题目链接:376. 摆动序列
思路:这道题乍一看,用动态规划做更合适一些(因为前后元素有明显的递推关系),但今天换一种思路,使用贪心算法来解一下。贪心的话,我们只需要考虑局部最优就行,如果每次都采用局部最优会得到全局最优,那我们的目的就达成了。
这道题,我们希望得到尽可能长的摆动序列(而且没有要求必须是连续子序列),所以当我们遇到不是摆动序列的第一个元素的时候,尝试直接将其删除(实际上不需要删除,不记录这个数即可),然后不断更新当前值与前后两个数字的差值即可。事实证明,这个思路是可行的。
但还有一个细节,就是序列左右两端结合这个方法无法很好的做判断,所以我们可以假设最左边有一个虚拟的、和最左端数值相同的哨兵(或者最右边有一个虚拟的、和最右端数值相同的虚拟数值),这样不会漏掉最左边或者最右边的数值。
go版本:
func wiggleMaxLength(nums []int) int {
if len(nums)==1 {return 1}
curDiff, preDiff, res := 0, 0, 1
for i:=1; i<len(nums); i++ {
curDiff = nums[i]-nums[i-1]
if (curDiff > 0 && preDiff <= 0) || (preDiff >= 0 && curDiff < 0) {
res++
preDiff = curDiff
}
}
return res
}
时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1)
LeetCode 53. 最大子数组和
题目链接:53. 最大子数组和
思路:同理,此题用动态规划会非常舒服,但今天对贪心算法进行一下特训,尝试一下别的思路亦是好事。此题与上一题有一个细节,要求我们找的是连续子数组。我们在遍历数组的时候,同时记录下当前的值。然后有两种判断情况:
- 如果当前最大的值为负数,那直接舍弃(之前的所有数),因为不管后续数多小,加上一个负数也只会更小;
- 如果当前的值大于我们储存的最大值,那直接将储存的值替换成当前值(贪心思想)。
go版本:
func maxSubArray(nums []int) int {
res := ^int(^uint(0) >> 1)
tmp := 0
for i:=0; i<len(nums); i++ {
tmp += nums[i]
if tmp > res {
res = tmp
}
if tmp<0 {
tmp = 0
}
}
return res
}
时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1)