Notion에서 작성한 글이라, 여기에서 더 깔끔하게 보실 수 있습니다! 😮😊
def bs_ub(self, a, v):
lo, hi = 0, len(a)-1
while lo <= hi:
mid = (lo+hi)//2
if a[mid] <= v:
lo = mid+1
else:
hi = mid-1
return lo
def findMaximizedCapital(self, k: int, w: int, profits: list[int], capital: list[int]) -> int:
proj = sorted(zip(capital, profits))
i = 0
possible = []
for _ in range(k):
while i < len(proj) and proj[i][0] <= w:
possible.insert(self.bs_ub(possible, proj[i][1]), proj[i][1])
i += 1
if possible: w += possible.pop()
else: break
return w
capital
로 w
과 비교하고, 그 인덱스에 대응하는 profits
의 값을 이용해야 하므로 같이 관리하기 좋게 zip()
으로 묶어준다.capital
이 낮은 proj
부터 순회하며 가능한 프로젝트의 목록(possible
)을 갱신해준다.possible
리스트는 정렬된 상태임을 생각하면, 이분 탐색을 이용하여 삽입될 원소가 들어갈 자리를 에 구할 수 있고, 그 자리에 삽입한다.profits
에 대하여 최대한 리스트의 오른쪽에 삽입하는 것이 삽입에 더 짧은 시간이 소요되므로 Upper bound를 이용한다.capital
의 값이 증가함에 따라 profits
의 값도 증가하는 경향을 가진 테스트 케이스들(possible
의 상대적으로 뒷부분에 insert하는 경우)로 구성된 것인지, 삽입에 많은 시간이 걸리지 않아 통과된다.def findMaximizedCapital(self, k: int, w: int, profits: list[int], capital: list[int]) -> int:
proj = sorted(zip(capital, profits), key=lambda x: x[0])
i = 0
possible = []
for _ in range(k):
while i < len(proj) and proj[i][0] <= w:
heappush(possible, -proj[i][1])
i += 1
if possible: w -= heappop(possible)
else: break
return w
profits
는 heap
에 push될 때 정렬 과정을 수행한 뒤 push된다는 점을 생각하면, 미리 정렬해놓을 필요가 없다. 따라서, 정렬 시 capital
만을 기준으로 정렬하도록 key=lambda x: x[0]
으로 지정하면, 같은 capital
값을 가질 때 profits
는 비교하지 않기 때문에 조금이라도 빨라질 여지가 있다.이를 다르게 생각하면 zip()
으로 묶지 않고 enumerate()
로 인덱스만 갖고 있는 방법도 생각해볼 수 있다. 아래 두 줄만 변경해주면 된다.
proj = sorted(enumerate(capital), key=lambda x: x[1])
heappush(possible, -profits[proj[i][0]])
def findMaximizedCapital(self, k: int, w: int, profits: List[int], capital: List[int]) -> int:
proj = [*zip(capital, profits)]
heapify(proj)
possible = []
for _ in range(k):
while proj and proj[0][0] <= w:
heappush(possible, -heappop(proj)[1])
if possible: w -= heappop(possible)
else: break
return w
capital
의 최솟값을 기준으로 계속해서 갱신한다는 점을 생각하면, 이 또한 이 걸리는 정렬이 아닌 이 걸리는 heapify()
를 이용할 수 있다.possible
을 갱신할 때마다 의 시간이 추가로 소모되어 이 또한 최악의 경우( 기존 방식과 같은 시간이 걸리며,