122.买卖股票的最佳时机II
思路
假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]
。
局部最优:收集每天的正利润,全局最优:求得最大利润。
代码
class Solution:
def maxProfit(self, prices: List[int]) -> int:
res = 0
for i in range(1, len(prices)):
diff = prices[i] - prices[i-1]
if diff > 0:
res += diff
return res
复杂度分析
- 时间复杂度:
O(n)
- 空间复杂度:
O(1)
55. 跳跃游戏
思路
每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
要点
有一点需要注意的是,在遍历的过程中如果遍历到的元素的index是超出覆盖的范围的,此时就要return False了,这意味着跳不过去。
代码
class Solution:
def canJump(self, nums: List[int]) -> bool:
length = 0
n = len(nums)
if len(nums) <= 1:
return True
for i in range(n-1):
# 重要
if i <= length:
length = max(length, i + nums[i])
if length >= n-1:
return True
return False
复杂度分析
- 时间复杂度:
O(n)
- 空间复杂度:
O(1)
45.跳跃游戏II
思路
统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖。
从图中可以看出来,就是移动下标达到了当前覆盖的最远距离下标时,步数就要加一,来增加覆盖距离。最后的步数就是最少步数。
这里还是有个特殊情况需要考虑,当移动下标达到了当前覆盖的最远距离下标时
- 如果当前覆盖最远距离下标不是是集合终点,步数就加一,还需要继续走。
- 如果当前覆盖最远距离下标就是是集合终点,步数不用加一,因为不能再往后走了。
代码
class Solution:
def jump(self, nums: List[int]) -> int:
res = 0
n = len(nums)
if n == 1:
return 0
curDis = 0
nextDis = 0
for i in range(n):
nextDis = max(nums[i] + i, nextDis)
if i == curDis:
res += 1
curDis = nextDis
if curDis >= n - 1:
break
return res
复杂度分析
- 时间复杂度:
O(n)
- 空间复杂度:
O(1)