|
29 | 29 |
|
30 | 30 | --- |
31 | 31 |
|
32 | | -業配我的 Github 跟解法: [louis222220 - No. 973 in TypeScript](https://github.com/louis222220/leetcode-practice/commit/fcf507e23cb954cc7e78444239fd98305af149b5) |
33 | 32 |
|
34 | | -- 嘗試優化:提前把所有點的距離算出來,再做排序,減少排序期間做了多餘的距離計算 |
35 | | - |
| 33 | +```python |
| 34 | +from typing import List |
| 35 | +import heapq |
| 36 | +class Solution: |
| 37 | + def furthestBuilding(self, heights: List[int], bricks: int, ladders: int) -> int: |
| 38 | + # a. use ladder optimally |
| 39 | + # keep tracking the usage of bricks |
| 40 | + # and if the sum of usage is more than bricks we have, we'll need ladder anyway) |
| 41 | + # use the ladder at the 'biggest gap', and minus from the sum of usage |
| 42 | + |
| 43 | + # b. use bricks optimally |
| 44 | + # the other way around is to use bricks optimally: |
| 45 | + # keep add gaps into the heap, and we only pop out the 'smallest gap' for brick usage |
| 46 | + |
| 47 | + # time O(N*logN), where N is the length of heights |
| 48 | + # space O(N) |
| 49 | + |
| 50 | + prev = float('inf') # 最大的 |
| 51 | + hp = [] # heap of brick usage |
| 52 | + brick_needed = 0 # sum of gaps |
36 | 53 |
|
37 | | -Louis 提議下次 1642 if end early we can do 295 (hard) Problem brief |
| 54 | + for i in range(len(heights)): |
38 | 55 |
|
| 56 | + # use ladder optimally |
| 57 | + if heights[i] > prev: |
| 58 | + brick_needed += heights[i]-prev |
| 59 | + heapq.heappush(hp, prev-heights[i]) |
| 60 | + if brick_needed > bricks: |
| 61 | + if ladders > 0: |
| 62 | + brick_needed += heapq.heappop(hp) # max heap (update brick_needed so we don't need so much) |
| 63 | + # a.k.a. brick_needed -= -heapq.heappop(hp) |
| 64 | + ladders -= 1 |
| 65 | + else: |
| 66 | + return i-1 |
39 | 67 |
|
40 | | ---- |
| 68 | + # use bricks optimally |
| 69 | + # if heights[i] > prev: |
| 70 | + # heapq.heappush(hp, heights[i]-prev) |
| 71 | + # if len(hp) > ladders: |
| 72 | + # brick_needed += heapq.heappop(hp) |
| 73 | + # if brick_needed > bricks: |
| 74 | + # return i-1 |
| 75 | + |
| 76 | + prev = heights[i] |
| 77 | + |
| 78 | + |
| 79 | + return len(heights)-1 |
| 80 | +``` |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | +```python |
| 85 | +# 871 |
| 86 | +from typing import List |
| 87 | +import collections |
| 88 | +class Solution: |
| 89 | + def minRefuelStops(self, target: int, startFuel: int, stations: List[List[int]]) -> int: |
| 90 | + # use DP |
| 91 | + if target > startFuel+sum([f for _, f in stations]): return -1 |
| 92 | + if not stations: return 0 if startFuel >= target else -1 |
| 93 | + |
| 94 | + # DP / dict (times of refuel) |
| 95 | + # key = refill times, value: remaining Fuel |
| 96 | + trips = {0:startFuel} |
| 97 | + pos, i = 0, 0 |
| 98 | + minRefill = float('inf') |
| 99 | + |
| 100 | + while pos < target and i < len(stations): |
| 101 | + stationPosition, stationFuel = stations[i] |
| 102 | + tmp = collections.defaultdict() |
| 103 | + # print('trips:', trips, 'min refills:', minRefill, 'pos:', pos, 'dis', stationPosition-pos) |
| 104 | + |
| 105 | + for refills, remainingFuel in trips.items(): |
| 106 | + # print('refill, fuel, pos', refills, remainingFuel, pos) |
| 107 | + if pos + remainingFuel >= target: |
| 108 | + minRefill = min(minRefill, refills) |
| 109 | + elif refills > minRefill or pos + remainingFuel < stationPosition: |
| 110 | + continue |
| 111 | + else: |
| 112 | + dist = stationPosition-pos |
| 113 | + if refills in tmp: |
| 114 | + tmp[refills] = max(tmp[refills], remainingFuel-dist) |
| 115 | + else: |
| 116 | + tmp[refills] = remainingFuel-dist |
| 117 | + if refills+1 in tmp: |
| 118 | + tmp[refills+1] = max(tmp[refills+1], remainingFuel-dist+stationFuel) |
| 119 | + else: |
| 120 | + tmp[refills+1] = remainingFuel-dist+stationFuel |
| 121 | + |
| 122 | + pos, trips = stationPosition, tmp |
| 123 | + i += 1 |
| 124 | + # print('trips now:', trips, 'at pos: ', pos) |
| 125 | + |
| 126 | + # print('trips:', trips, 'min refills:', minRefill, 'pos:', pos, 'i', i) |
| 127 | + if pos < target and i == len(stations): |
| 128 | + for refills, remainingFuel in trips.items(): |
| 129 | + if pos + remainingFuel >= target: |
| 130 | + minRefill = min(minRefill, refills) |
| 131 | + return -1 if minRefill == float('inf') else minRefill |
| 132 | + |
| 133 | + return min([k for k, _ in trips]) |
| 134 | +``` |
| 135 | + |
| 136 | +Y.J. Lee下午8:15 |
| 137 | +大概兩種解法 |
| 138 | +optimally use the 1. ladder or 2. brick |
| 139 | +會牽涉到 using max-heap or min-heap |
| 140 | +Y.J. Lee下午8:20 |
| 141 | +那個是backtracking |
| 142 | +Y.J. Lee下午8:22 |
| 143 | +嗯 我講的backtracking 單純指 undo 前一動 |
| 144 | +Y.J. Lee下午8:24 |
| 145 | +你得到它了 |
| 146 | +Louis Su下午8:28 |
| 147 | +o(〃’▽’〃)o |
| 148 | +Y.J. Lee下午8:30 |
| 149 | +阿六的質因數分解吧? |
| 150 | +Y.J. Lee下午8:32 |
| 151 | +我覺得不太像 |
| 152 | +但是這個多路並歸我沒聽過QQ |
| 153 | +Y.J. Lee下午8:34 |
| 154 | +都沒人寫喔 我把我的寫法先丟hackmd好了 大家可以討論 |
| 155 | +XD 加油站那題 我好像也有 找找 |
| 156 | +你下午8:36 |
| 157 | +871 |
| 158 | +Y.J. Lee下午8:37 |
| 159 | +Naive 不用看 |
| 160 | +Y.J. Lee下午8:38 |
| 161 | +萬惡 python maxheap 是負的XD |
| 162 | +底下就是 minheap |
| 163 | +Y.J. Lee下午8:40 |
| 164 | +871 我是用DP喔 |
| 165 | +Y.J. Lee下午8:42 |
| 166 | +#1642這個做法應該就遍歷 array, 但是過程中 maintain 一個heap (either min or max) |
| 167 | +Y.J. Lee下午8:44 |
| 168 | +sudoku 這個滿經典的 backtracking |
| 169 | +畫到某一格 沒步了 前面某一步一定有錯 先回溯上一步再繼續 |
| 170 | +Y.J. Lee下午8:47 |
| 171 | +#1642 的問題在於他沒步了不一定不是最佳解 所以變成要遍歷整個樹 會很恐怖 |
| 172 | +沒看 +1 XD |
| 173 | +Y.J. Lee下午8:50 |
| 174 | +其實dfs就很類似啦 很多情境你會直接想到dfs而不是backtracking |
| 175 | +Y.J. Lee下午8:52 |
| 176 | +dfs 的 recursive call 如果有把前面做的事情undo 就會八成像 backtracking |
| 177 | +Y.J. Lee下午8:53 |
| 178 | +所以我聽到 backtracking 會直覺有 undo 某些東西 |
0 commit comments