解析
45. Jump Game II
- 不断的向右跳,每一跳之前,探测这一跳可以到的每个位置的索引,记下最大的索引,并跳到这里
- 有点像BFS
def jump(self, nums: List[int]) -> int:
l, r = 0, 0
count = 0
while r < len(nums) - 1: # before r reaches the last index, continue
farthest = 0
for i in range(l, r + 1):
farthest = max(farthest, i + nums[i])
l = r + 1 # because it is guaranteed that I can rach the last index
r = farthest
count += 1
return count
ref
53. Maximum Subarray
- 不断贪心的找最大的当前和
- 如果之前的和小于0,就重置 cur_sum 成 0 ,因为 小于 0 的和并不能contribute任何。然后考虑当前元素
- 如果之前的和大于0,就继续考虑(累加)当前元素
# 写法 1
def maxSubArray(self, nums: List[int]) -> int:
cur_max = nums[0]
cur_sum = 0
for num in nums:
if cur_sum < 0:
cur_sum = 0
cur_sum += num
cur_max = max(cur_max, cur_sum)
return cur_max
# 写法 2
def maxSubArray(self, nums: List[int]) -> int:
cur_max_sum = nums[0]
cur_sum = cur_max_sum
for i in range(1, len(nums)):
num = nums[i]
if cur_sum > 0:
cur_sum += num
else: # the previous sum doesn't help, and thus reset cur_sum to be current num. 0 doesn't help, and thus the condition is > 0
cur_sum = num
cur_max_sum = max(cur_max_sum, cur_sum)
return cur_max_sum
ref
55. Jump Game
- 先把 goal 设置在最右边的位置
- 不断向左循环,看看能不能从当前位置跳到 goal,如果可以,把当前位置设置为 goal(因为当前位置可以跳到 goal)
- 最后看看当前的 goal是不是为0,为0表示当前的goal就是起跳的位置
# solution 1
def canJump(self, nums: List[int]) -> bool:
goal = len(nums) - 1
for i in range(len(nums) - 1, -1, -1):
if i + nums[i] >= goal:
goal = i
return goal == 0
# solution 2
def canJump(self, nums: List[int]) -> bool:
l = 0
r = 0 + nums[0]
while True:
cur_l = l
cur_r = r
for i in range(cur_l, cur_r + 1):
r = max(r, i + nums[i])
if r >= len(nums) - 1:
return True
if r == cur_r:
return False
l = cur_r + 1
ref
134. Gas Station
- time: O(n), space: O(1)
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
if sum(gas) < sum(
cost): # If this case, we know that we are not able to finish the route in any ways, because we know that the total gas is not enough
return -1
# If comes to here, we guarantee that we are able to finish the circular route
left = 0
res = 0
for idx in range(len(gas)):
left += gas[idx] - cost[idx]
if left < 0:
res = idx + 1
left = 0
# Because every time we pass every gas station and left >= 0, and sum(cost) <= sum(gas), so the pgas needed for the gas stations that we haven't gone through will be < than the left.
return res
ref
678. Valid Parenthesis String
- 这题好难,暂时跳过了
def checkValidString(self, s: str) -> bool:
# ( * ) * ( )
minLeft = 0
maxLeft = 0
# space: O(1)
# time: O(n)
for char in s:
if char == "(":
minLeft += 1
maxLeft += 1
elif char == ")":
minLeft -= 1
maxLeft -= 1
else:
minLeft -= 1
maxLeft += 1
if maxLeft < 0: # e.g., ))((
return False
if minLeft < 0: # we need this if because of s = ( * ) ( case
minLeft = 0
return minLeft == 0
ref
763. Partition Labels
- 贪心的去比较 max_last_idx
def partitionLabels(self, s: str) -> List[int]:
# get the last index of every element
lastIndex = {}
for idx in range(len(s)):
char = s[idx]
lastIndex[char] = idx
res = []
max_last_idx = 0
size = 0
for idx in range(len(s)):
char = s[idx]
max_last_idx = max(max_last_idx, lastIndex[char])
size += 1
if idx == max_last_idx: # reach the last index of all elements that we have seen
res.append(size)
size = 0 # reset the size
return res
ref
846. Hand of Straights
- use min heap to get the min clementi by O(1)
- get the element starting from the min, until we have
groupSize
elements
def isNStraightHand(self, hand: List[int], groupSize: int) -> bool:
if len(hand) % groupSize != 0:
return False
m = {}
for ele in hand:
m[ele] = m.get(ele, 0) + 1
minHeap = list(m.keys())
heapq.heapify(minHeap)
while minHeap:
cur_min = minHeap[0]
for i in range(cur_min, cur_min + groupSize):
if i not in m:
return False
m[i] -= 1
if m[i] == 0:
if i != minHeap[0]:
return False
heapq.heappop(minHeap)
return True
ref
1899. Merge Triplets to Form Target Triplet
def mergeTriplets(self, triplets: List[List[int]], target: List[int]) -> bool:
hasX = False
hasY = False
hasZ = False
for triplet in triplets:
if triplet[0] > target[0] or triplet[1] > target[1] or triplet[2] > target[
2]: # Not consider such a triplet, since any of elements of this triplet is > than the corrsponding element in the target array, we shouldn't consider this triplet, otherwise, we cannot form target if we use this triplet, e.g., triplet: [2,8,3] target: [2,7,3] -> the final triplet will be [x,8,x]
continue
# Then, for all triplets come to here, the element will <= the element of the target, and if = for all three elements, we are sure that we can make it somehow
if triplet[0] == target[0]:
hasX = True
if triplet[1] == target[1]:
hasY = True
if triplet[2] == target[2]:
hasZ = True
return hasX and hasY and hasZ
ref