写代码的第二十三天
进入贪心!加油呀!
贪心算法贪的是什么。。。。。。
理论基础
没有模版,不要想着去证明!找到局部最优解即可!
455.分发饼干
思路
解决问题1:局部最优解是什么?让大饼干满足胃口大的孩子或者小饼干满足胃口小的孩子。如果说让大饼干满足胃口小的孩子,确实是可以满足,但是会导致胃口大的孩子没有可以被满足的饼干,那最后的结果就不是尽可能满足越多数量的孩子。要让饼干的利用最大化。要做到这一步首先就需要排序,将胃口与饼干大小从小到大排序,这样通过循环就可以不断的比较胃口和饼干的大小。很容易想到用for循环遍历,但是这个for循环应该遍历胃口还是饼干大小呢?
大饼干满足胃口大的孩子:大饼干满足大胃口,所以应该是从后向前进行for循环比较,如果for循环遍历的是饼干的大小,那么也就是说代表饼干大小的数组是不断的-1的向前走的,无论有没有满足的投喂小孩这个操作都要向前走,比如这样一个情况(孩子胃口是1,2,3,10,饼干大小是1,3,5,9,那么当遍历饼干的时候9是不满足最后一个孩子的,然后for循环继续向前走5也不满足,继续向前走3也不满足,继续走1也不满足,所以结果就是用这个for循环一个孩子的胃口都没满足,输出了错误的结果)所以应该是的外层for循环遍历胃口,用胃口去比较饼干大小。
小饼干满足胃口小的孩子:小饼干满足小胃口应该是从前向后遍历,如果for循环遍历的是胃口大小,那么也会出现上面的情况,就是遍历结束一个满足条件的都没有,所以应该用for循环遍历饼干大小。
解决问题2:是否有反例可以推翻上面的局部最优解?没有。可以写代码了。
正确代码1:大饼干大胃口
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
g = sorted(g)
s = sorted(s)
result = 0
index = len(s) - 1
for i in reversed(g):
if index >= 0 and i <= s[index]:
result += 1
index -= 1
return result
正确代码2:小饼干小胃口
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
g = sorted(g)
s = sorted(s)
result = 0
index = 0
for i in range(len(s)):
if index < len(g) and s[i] >= g[index]:
result += 1
index += 1
return result
376. 摆动序列
思路
一点思路都没有,直接看了卡哥的视频。
求最长摆动序列,也就是把原始序列中不产生摆动的数字删掉,剩下的就是最长的摆动序列了。
举个例子画个图就明白了,在这个图中我们要求的最长摆动子序列其实就是所有的波峰和波谷的点的个数。
所以产生摆动的条件是当前结点前面差值为负,后面为正;或者前面差值为正,后面为负。
错误第一版:这种测试用例不通过。也就是说当测试用例中出现了相同的数字这种情况还没解决。之前的代码比较的都是前面正后面负,前面负后面正这种情况,没考虑前面后面为0这种情况,通过这个测试用例可以将判断条件改为前面大于等于零后面小于0;或者前面小于等于零后面大于零,前后不能同时为零,那样的话没有波峰和波谷。
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
result = 1
for i in range(len(nums)-1):
prediff = nums[i] - nums[i-1]
curdiff = nums[i+1] - nums[i]
if (prediff > 0 and curdiff < 0) or (prediff < 0 and curdiff > 0):
result += 1
return result
错误第二版:以下测试用例没通过。如果同时出现了数值相等,但是有只是单调向上或向下的测试用例这种情况没有考虑到。prediff的更新没有在每次迭代结束后进行,而是在下一次迭代中,导致逻辑错误。所以应该在每次迭代中,prediff更新为curdiff的值,以便在下一次迭代中正确比较相邻元素的差值。
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
result = 1
for i in range(len(nums)-1):
prediff = nums[i] - nums[i-1]
curdiff = nums[i+1] - nums[i]
if (prediff >= 0 and curdiff < 0) or (prediff <= 0 and curdiff > 0):
result += 1
return result
正确代码:
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
result = 1
prediff = 0
for i in range(len(nums)-1):
curdiff = nums[i+1] - nums[i]
if (prediff >= 0 and curdiff < 0) or (prediff <= 0 and curdiff > 0):
result += 1
prediff = curdiff
return result
53. 最大子序和
思路
贪心算法贪的是什么?(卡哥的讲解醍醐灌顶)当和为负数的时候立即抛弃,然后去找下一位,把下一位当作子序的起点在继续计算,count归零。
正确代码:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
sums = float('-inf')
count = 0
for i in range(len(nums)):
count += nums[i]
if count > sums:
sums = count
if count < 0:
count = 0
return sums