贪心第二天,122. 买卖股票的最佳时机 II,55. 跳跃游戏,45. 跳跃游戏 II,1005. K 次取反后最大化的数组和。依旧是感觉贪心像是智力题能想的出来就好写,想不出来真就是被绕进去。像是股票Ⅱ,一开始想的必须是必须低点买入直到高点才能卖出,忽略了这个过程中一直不停买卖也是一样的结果,能想清楚这个就会很容易。贪心真是一题一个样,每道题都能多少卡一会,然后看题解的时候就会恍然大悟,质疑自己这么简单的思路为啥刚才想不出来,然后下一道题接着卡,这就是做贪心题。
55. 跳跃游戏,45. 跳跃游戏 II
两道思路类似的题目。Ⅰ是判断能否跳到最后一个数,Ⅱ是判断最短次数跳到最后一个数。一开始思考的思路是正确的,就是利用贪心,每一步都跳最远,然后去判断能否跳到最后/跳跃次数。但是做的时候发现个问题,就是类似2.7.1这种,如果在2跳到最远的1,实际上不如跳一步到7再跳。然后看题解学到了要用范围去理解这类题目,即不停使用i+nums[i]进行最大cover的维护。像在Ⅰ中,便是i不停向cover靠近,同时去不断更新这一段路程中,最远的点能跳到哪里,最后如果能cover到最后一个数就是True。举个反例[3,2,1,0,7]这里在i为0-2的时候,i+nums[i]都是3,所以只能cover到3,当i超过3之后,cover的值就不再更新了,也就是False。
Ⅱ是一样的cover思路,但是自己做的时候还是有错误。简单来说思路就是每次在当前跳跃范围内尽量向右扩展 next_distance,一旦走到当前层的边界,就执行一次跳跃并进入下一层,然后记录跳跃次数。就是类似于两层,一层是当前i正在循环的当前层,另外一层是最远层,每次i前进时,就记录这个最远层的最大值,当i在当前层走完时,当前层的最远点跳至最远层的最远点。也就是在一层遍历中,当前层中每个点的跳跃距离选最远的跳,最后记录跳多少次。
# 跳跃Ⅰ
class Solution:
def canJump(self, nums: List[int]) -> bool:
if len(nums) == 1: return True
cover = 0
for i in range(len(nums)):
if i <= cover:
cover = max(i+nums[i],cover)
if cover >= len(nums) - 1:
return True
return False
# 跳跃Ⅱ
class Solution:
def jump(self, nums: List[int]) -> int:
#每次在当前跳跃范围内尽量向右扩展 next_distance,一旦走到当前层的边界,就执行一次跳跃并进入下一层。
cur_distance = 0 # 当前覆盖的最远距离下标
ans = 0
next_distance = 0 # 下一步覆盖的最远距离下标
for i in range(len(nums) - 1): #跳到最后一个位置就行,最后一个位置无需跳跃判断
next_distance = max(nums[i] + i, next_distance) # 更新下一步覆盖的最远距离下标
if i == cur_distance: # 遇到当前覆盖的最远距离下标
cur_distance = next_distance # 更新当前覆盖的最远距离下标
ans += 1
return ans
1005. K 次取反后最大化的数组和
1005. K 次取反后最大化的数组和 - 力扣(LeetCode)
暴力做法确实简单,直接排序k次数组执行k次最小数的转换就行,就是复杂度飞上天了。
然后想了想其他思路,感觉卡住的点是在于0,就是当所有负数都转化了,k仍然有次数,该怎么办这种情况。
学到一种新的排序方法,就是原数组利用绝对值大小进行排序,类似排序成[3,2,-1,0]这种。然后先进行一次遍历,将所有负数先转换了,而且这样排序肯定转变的是更小的负数,转变完就变成更大值了。然后就是解决我刚才思考不出来的点,就是还有次数但没负数的情况。这里的解法就是判断K剩余次数的奇偶数,如果为偶,那就相当于把一个最小正数反转再反转,就是没变,所以也不用额外操作。当剩余次数为奇,就把数组最后一个(之前倒序排,最后一个肯定最小)反转了,这样可以保证为最大值。
class Solution:
def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
# 暴力
# for _ in range(k):
# nums.sort()
# nums[0] = -nums[0]
# return sum(nums)
nums.sort(key=lambda x: abs(x), reverse=True)
for i in range(len(nums)):
if nums[i] < 0 and k > 0:
nums[i] *= -1
k -= 1
if k % 2 == 1:
nums[-1] *= -1
return sum(nums)


被折叠的 条评论
为什么被折叠?



