一、122.买卖股票的最佳时机II
本题解法很巧妙, 本题大家可以先自己思考一下然后再看题解,会有惊喜!
1. 解题思路
用当天减去前一天的价格就得到当天的利润,计算出每天的利润后,选取利润为正数的天数作为买卖股票的最佳时机,然后将这几天的利润相加得到最大利润。
2. 代码实现
(1)定义result变量将每天的利润累加在一起,初始化为0;
(2)遍历price数组,从下标为1开始,因为需要有前一天才可以计算利润。如果利润是负数的话,result不加,如果利润是正数,result加上当天利润。
(3)最后返回result。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
result = 0
for i in range(1, len(prices)):
benefit = prices[i]-prices[i-1]
if benefit > 0:
result += benefit
return result
二、55. 跳跃游戏
本题如果没接触过,很难想到,所以不要自己憋时间太久,读题思考一会,没思路立刻看题解
1. 解题思路
无需去思考到底跳几步,而只需要看最大覆盖范围是否可以将数组完全覆盖,如果可以则返回True,反之False。
2. 代码实现
(1)定义变量cover为覆盖的下标,初始化为0;
(2)如果数组的长度等于1,说明只有一个元素,那么一定可以覆盖,因为起始位置在终止位置;
(3)for循环遍历,i 只能在覆盖范围内移动,所以 i 一定小于等于cover:将cover更新为 i 加上nums[i],也就是遍历当前范围内的元素,并让所遍历的元素位置 i 加上其最大移动步数,就可以更新最大覆盖范围。如果cover等于数组的最后一位,那么说明可以覆盖整个数组,返回True。
class Solution:
def canJump(self, nums: List[int]) -> bool:
cover = 0
if len(nums) == 1:
return True
for i in range(len(nums)):
if i <= cover:
cover = max(i+nums[i], cover)
if cover >= len(nums)-1:
return True
return False
三、45.跳跃游戏II
本题同样不容易想出来。贪心就是这样,有的时候 会感觉简单到离谱,有时候,难的不行,主要是不容易想到。
1. 解题思路
用最少的步数尽可能增加覆盖范围,一旦覆盖范围覆盖至终点,就将步数进行输出。
2. 代码实现
(1)当传入的数组长度等于1时,当前起点就是终点,无需挪动,所以挪动0步,直接返回0。
(2)定义cur变量记录当前覆盖范围,初始化为0。当当前覆盖范围还没到终点时,需要启动下一步的覆盖范围,所以定义next变量记录下一步的覆盖范围,初始化为0。定义变量result用于记录具体跳几步。
(3)for循环遍历数组:由于只需要下一步记录最远的覆盖距离,所以next只更新最远的覆盖距离,用 i 加上nums[ i ]。
如果 i 走到了当前覆盖范围的最大位置,也就是cur:
1)判断如果当前位置不是终点,那么result需要再向前一步进入下一个覆盖范围,并且将next赋给cur。如果当前覆盖距离覆盖到终点,那么break,当前result就是结果。
2)如果当前位置是终点,直接break。
class Solution:
def jump(self, nums: List[int]) -> int:
if len(nums) == 1:
return 0
result = 0
cur = 0
next = 0
for i in range(len(nums)):
next = max(i + nums[i], next)
if i == cur:
result += 1
cur = next
if cur >= len(nums)-1:
break
return result
四、1005.K次取反后最大化的数组和
本题简单一些,估计大家不用想着贪心 ,用自己直觉也会有思路。
1. 解题思路
本题蕴含了两个贪心:1)排序后的数组中,优先对最大的负数进行取反,可以使数组和最大化;2)如果数组全为正数,而k未使用完,那么在排序后对最小的正数进行取反。
2. 代码实现
(1)首先对数组进行按照绝对值从大到小排序。
(2)for循环遍历数组:如果遍历的元素小于0且k>0,那么对其乘以(-1),并且k减1。此时在k充足的情况下,数组中元素全为正数。
(3)第二次贪心:k可能还没消耗,当剩下的k是奇数的时候,直接对末尾元素乘以1;如果k是偶数,则末尾元素正负保持不变。
在Python中,
A.sort(key=lambda x: abs(x), reverse=True)
这行代码的作用是对列表A
进行排序。排序的依据是列表中每个元素的绝对值,并且是按照从大到小的顺序进行排序(因为reverse=True
)。这里有几个关键点需要解释:
A.sort()
:这是列表(List)的一个方法,用于就地(in-place)对列表进行排序,即直接修改原列表而不是返回一个新的排序后的列表。
key=lambda x: abs(x)
:key
参数用于指定一个函数,这个函数会被用于从每个列表元素中提取一个用于比较的关键字(key)。在这个例子中,lambda x: abs(x)
是一个匿名函数,它接受一个参数x
并返回x
的绝对值。这意味着排序将基于元素的绝对值进行。
reverse=True
:这个参数指定排序的顺序。默认情况下,sort()
方法会按照从小到大的顺序排序(reverse=False
)。当设置为True
时,排序顺序会变为从大到小。
class Solution:
def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
# 首先对nums按照绝对值由大到小进行排序
nums.sort(key = lambda x:abs(x), reverse = True)
# 遍历数组nums
for i in range(len(nums)):
if nums[i] < 0 and k > 0:
nums[i] *= (-1)
k -= 1
# 如果k还有剩下的且是奇数,此时数组已全是正数,并且数组末尾是最小正数,k可以用多次
# 那么对数组末尾元素进行取反即可
if k % 2 == 1:
nums[len(nums)-1] *= (-1)
# 对元素进行求和
result = sum(nums)
return result