2024년 1월 6일 (토)
Leetcode daily problem
주어진 작업들을 수행하여 최대 이익을 얻는 문제이다.
각 작업은 시작 시간(startTime), 종료 시간(endTime), 이익(profit)으로 구성되어 있으며, 한 작업을 수행하면 해당 작업의 종료 시간까지의 이익이 얻어진다. 동시에 두 개 이상의 작업을 수행할 수 없고, 작업들은 서로 겹치지 않아야 한다.
Dynamic programming + binary search
Dynamic programming으로만 풀면 time limit error가 발생한다.
그래서 Dynamic programming과 binary search를 같이 이용해야한다.
(1) 먼저 작업을 종료 시간을 기준으로 오름차순 정렬한다.
(2) 동적 프로그래밍(dp)를 사용하여 최대 이익을 계산한다.
각 작업에 대해 현재 작업을 선택했을 때의 최대 이익을 계산하느넫,
현재 작업의 이전에 종료된 작업 중에서 가장 큰 이익을 갖는 작업을 찾아야한다.
(3) 이진 탐색을 통해 현재 작업의 시작 시간보다 빨리 끝나는 작업 중 가장 큰 이익을 갖는 작업을 찾는다.
(4) 현재 작업을 선택했을 때의 최대 이익을 계산하여 dp table을 갱신한다.
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
ans = [1] * len(nums)
for i in range(len(nums)-2,-1,-1):
for j in range(i+1, len(nums)):
if nums[i] < nums[j]:
ans[i] = max(ans[i], 1+ans[j])
return max(ans)
시간 복잡도
이중 반복문을 사용하고 있으므로 O(n^2) 이다.
공간 복잡도
배열 nums의 길이에 비례하는 O(n) 이다.
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
tmp = [0]*len(nums)
size = 0
for num in nums:
left, right = 0, size
while left<right:
mid = (left+right)//2
if tmp[mid] < num:
left = mid+1
else:
right = mid
tmp[left] = num
if left == size:
size +=1
return size