tasks for today:
1. 134.加油站
2. 135.分发糖果
3. 860.柠檬水找零
4. 406.根据身高重建队列
---------------------------------------------------------------------------
1. 134.加油站
the first method, simulation, only applicable at small cases
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
if sum(gas) < sum(cost):
return -1
for i in range(len(gas)):
if gas[i] < cost[i]:
continue
new_gas = gas[i:] + gas[0:i+1]
new_cost = cost[i:] + cost[0:i+1]
cur = new_gas[0]
cur_remain = 0
steps = 0
for k in range(len(gas)):
cur_remain += new_gas[k]
if cur_remain - new_cost[k] + new_gas[k+1] >= new_cost[k+1]:
steps += 1
cur_remain -= new_cost[k]
else:
break
if steps == len(gas):
return i
return -1
Greedy method: calculate the sum of rest petrol/gas, when the sum is negative, then [0, i] should not be the start point.
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
if sum(gas) < sum(cost):
return -1
curSum = 0
totalSum = 0
i = 0
start = 0
for i in range(len(gas)):
curSum += gas[i] - cost[i]
totalSum += gas[i] - cost[i]
if curSum < 0:
start = i + 1
curSum = 0
if totalSum < 0:
return -1
else:
return start
2. 135.分发糖果
In this practice, the key is not trying to handle both sides at one single traverse, try to traverse from left to right and then from right to left.
class Solution:
def candy(self, ratings: List[int]) -> int:
candyVector = [1] * len(ratings)
for i in range(1, len(ratings)):
if ratings[i] > ratings[i-1]:
candyVector[i] = candyVector[i-1] + 1
for i in range(len(ratings)-2, -1, -1):
if ratings[i] > ratings[i+1]:
candyVector[i] = max(candyVector[i+1] + 1, candyVector[i])
return sum(candyVector)
3. 860.柠檬水找零
simulation, the key is when receiving a 20, aiming to reserve 5 as many as possible, give 10 with priority, reserving 5.
class Solution:
def lemonadeChange(self, bills: List[int]) -> bool:
if bills[0] > 5:
return False
pocket = [5]
num_five = 1
for i in range(1, len(bills)):
if bills[i] == 5:
pocket.append(5)
num_five += 1
elif bills[i] == 10:
if 5 not in pocket:
return False
else:
pocket.append(10)
pocket.pop(pocket.index(5))
num_five -= 1
elif bills[i] == 20:
if sum(pocket) < 15:
return False
elif 5 not in pocket:
return False
elif 5 not in pocket and 10 not in pocket:
return False
elif 10 in pocket and 5 in pocket:
pocket.append(20)
pocket.pop(pocket.index(5))
pocket.pop(pocket.index(10))
num_five -= 1
elif num_five >= 3:
pocket.append(20)
pocket.pop(pocket.index(5))
pocket.pop(pocket.index(5))
pocket.pop(pocket.index(5))
num_five -= 3
else:
return False
# print(pocket)
return True
4. 406.根据身高重建队列
Similar to practice 135, when there are two dimention factors, dealing with each dimention one by one.
In this practice, we first deal with the hight, sort the people tuple list adhering to the hight in descending order, when the hight is the same then adhering to the second dim.
Then repermute the tuple adhering to the second dimention.
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
people.sort(key = lambda x: (-x[0], x[1]))
que = []
for p in people:
que.insert(p[1], p)
return que