45.跳跃游戏 II*
这个与跳跃游戏的区别在于,对每一个cover,我们在这个cover内每一个i里面寻找下一个最大的cover,直到最大的才更新。
而跳跃游戏解法是,对每一个cover,我们遍历这个cover内的i同时更新cover,直到cover能覆盖整个nums
例子:
# [7,0,9,6,9,6,1,7,9,0,1,2,9,0,3,1]
跳跃游戏
# i: 0 1 2 3 4 5 6 7 8
#cover: 7 7 11 11 13 13 13 14 17 > 15 end
跳跃游戏二:
i, (i,cover+1), cover, count
0, (0, 1), 7, 2
0, (0, 8), 14, 3
0, (7, 15), 17>15, return 3
class Solution:
def jump(self, nums: List[int]) -> int:
if len(nums) == 1:
return 0
i, cover = 0, 0
count = 1
while i <= cover:
for i in range(i, cover + 1):
cover = max(i + nums[i], cover)
if cover >= len(nums) - 1:
return count
count += 1
1005.K次取反后最大化的数组和
给你一个整数数组 nums
和一个整数 k
,按以下方法修改该数组:
- 选择某个下标
i
并将nums[i]
替换为-nums[i]
。
重复这个过程恰好 k
次。可以多次选择同一个下标 i
。
以这种方式修改数组后,返回数组 可能的最大和 。
我的解法:
class Solution:
def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
nums.sort()
for i in range(len(nums)):
if nums[i] < 0 and k > 0:
nums[i] = -nums[i]
k -= 1
elif nums[i] >= 0:
break
if k % 2 == 1 and nums[i] < nums[i-1]:
nums[i] = -nums[i]
elif k % 2 == 1 and nums[i] >= nums[i-1]:
nums[i-1] = -nums[i-1]
return sum(nums)
随想录解法:
用到了lambda函数,按绝对值从大到小排序,A.sort(key=lambda x: abs(x), reverse=True)
class Solution:
def largestSumAfterKNegations(self, A: List[int], K: int) -> int:
A.sort(key=lambda x: abs(x), reverse=True) # 第一步:按照绝对值降序排序数组A
for i in range(len(A)): # 第二步:执行K次取反操作
if A[i] < 0 and K > 0:
A[i] *= -1
K -= 1
if K % 2 == 1: # 第三步:如果K还有剩余次数,将绝对值最小的元素取反
A[-1] *= -1
result = sum(A) # 第四步:计算数组A的元素和
return result
134. 加油站*
在一条环路上有 n
个加油站,其中第 i
个加油站有汽油 gas[i]
升。
你有一辆油箱容量无限的的汽车,从第 i
个加油站开往第 i+1
个加油站需要消耗汽油 cost[i]
升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas
和 cost
,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1
。如果存在解,则 保证 它是 唯一 的。
这一题的重点就是:当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行。
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
cur_gas = 0
total_gas = 0
# 注意起始的start为0 eg: [3,1,1] [1,2,2], cur_gas 一直大于等于零,start应该是0
start = 0
for i in range(len(gas)):
cur_gas += gas[i] - cost[i]
total_gas += gas[i] - cost[i]
if cur_gas < 0:
start = i + 1
cur_gas = 0
if total_gas < 0:
return -1
else:
return start
135. 分发糖果*
n
个孩子站成一排。给你一个整数数组 ratings
表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到
1
个糖果。 - 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
我的解答:不对,如果出现分数连续递减的情况就不对了
class Solution:
def candy(self, ratings: List[int]) -> int:
# [1,3,2,2,1]
# 1,2,1,2,1
# [1,2,87,87,87,2,1]
# 1, 2, 3, 1, 3,2,1
n = len(ratings)
if n == 1:
return 1
pre_candy = 0
pre_candy = 1 if ratings[0] <= ratings[1] else 2
candy = pre_candy
for i in range(1, n):
if ratings[i] > ratings[i-1]:
candy += pre_candy + 1
pre_candy += 1
else:
if i + 1 <= n - 1 and ratings[i] > ratings[i+1]:
candy += 2
pre_candy = 2
elif pre_candy > 1:
candy += 1
pre_candy = 1
else:
candy += pre_candy
return candy
随想录解法:
class Solution:
def candy(self, ratings: List[int]) -> int:
# [1,2,87,87,87,2,1]
# 从左向右 只考虑左边:1,2,3,1,1,1,1
# 从右到左 只考虑右边:1,1,1,1,3,2,1
# 取相对大, 得到结果:1,2,3,1,3,2,1
n = len(ratings)
candy = [1] * n
for i in range(1, n):
if ratings[i] > ratings[i - 1]:
candy[i] = candy[i-1] + 1
for i in range(n-2, -1, -1):
if ratings[i] > ratings[i+1]:
candy[i] = max(candy[i+1] + 1, candy[i])
return sum(candy)
860.柠檬水找零
在柠檬水摊上,每一杯柠檬水的售价为 5
美元。顾客排队购买你的产品,(按账单 bills
支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5
美元、10
美元或 20
美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5
美元。
注意,一开始你手头没有任何零钱。
给你一个整数数组 bills
,其中 bills[i]
是第 i
位顾客付的账。如果你能给每位顾客正确找零,返回 true
,否则返回 false
。
我的解法:
class Solution:
def lemonadeChange(self, bills: List[int]) -> bool:
change_count = {'5': 0, '10': 0}
# [5,5,10,20,5,5,5,5,5,5,5,5,5,10,5,5,20,5,20,5]
for i in range(len(bills)):
if bills[i] == 10:
change_count['10'] += 1
change_count['5'] -= 1
elif bills[i] == 20:
if change_count['10'] > 0:
change_count['10'] -= 1
change_count['5'] -= 1
else:
change_count['5'] -= 3
else:
change_count['5'] += 1
if change_count['5'] < 0 or change_count['10'] < 0:
return False
return True
随想录解法:思路一样不过具体实现方案略有不同
class Solution:
def lemonadeChange(self, bills: List[int]) -> bool:
five = 0
ten = 0
twenty = 0
for bill in bills:
# 情况一:收到5美元
if bill == 5:
five += 1
# 情况二:收到10美元
if bill == 10:
if five <= 0:
return False
ten += 1
five -= 1
# 情况三:收到20美元
if bill == 20:
# 先尝试使用10美元和5美元找零
if five > 0 and ten > 0:
five -= 1
ten -= 1
#twenty += 1
# 如果无法使用10美元找零,则尝试使用三张5美元找零
elif five >= 3:
five -= 3
#twenty += 1
else:
return False
return True