Skip to content

Commit 0b38772

Browse files
committed
Longest Increasing Subsequence - 풀이 추가
1 parent 8d3745d commit 0b38772

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

longest-increasing-subsequence/forest000014.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
11
/*
2-
Time Complexity: O(nlogn)
3-
Space Complexity: O(nlogn)
2+
# Time Complexity: O(nlogn)
3+
- tuples ArrayList 정렬: O(nlogn)
4+
- 인덱스 트리 삽입: O(logn) * n times = O(nlogn)
5+
- 인덱스 트리 조회: O(logn) * n times = O(nlogn)
6+
7+
# Space Complexity: O(nlogn)
8+
- tuples ArrayList: O(n)
9+
- 인덱스 트리: O(nlogn)
10+
11+
# solution
12+
이 문제는 DP로 접근했습니다.
13+
14+
LIS(1, x)를 범위 [1, x] 내의 LIS(단, nums[x]를 반드시 포함)의 길이라고 정의하겠습니다. - (1)
15+
1 <= j < i 인 모든 j에 한 LIS(1, j)를 알고 있다면, LIS(1, i)는 아래와 같이 구할 수 있습니다.
16+
LIS(1, i) = max(LIS(1, j)) (단, j는 1 <= j < i 이고, nums[j] < nums[i]) - (2)
17+
18+
max(LIS(1, j))를 구할 때, 모든 j에 대해 탐색한다면, 전체 시간 복잡도는 O(n^2)가 되기 때문에, 시간 복잡도를 줄일 필요가 있습니다.
19+
이 탐색 과정을 줄이기 위해, 아래의 사고 과정을 거쳤습니다.
20+
21+
어떤 범위 내의 가장 큰 값을 O(logn) 시간에 구하기 위한 자료구조로, 인덱스 트리(혹은 세그먼트 트리)를 사용합니다.
22+
(이 인덱스 트리의 x번째 leaf 노드에는 LIS(1, x) 값을 저장하고, internal 노드에는 자식 노드들 중 가장 큰 값을 저장합니다.)
23+
24+
다만, 단순히 해당 범위 내의 가장 큰 값을 구하는 것만으로는 부족하고, nums[j] < nums[i]인 j만을 후보로 삼아야 할 텐데요,
25+
그러기 위해서, 인덱스 트리에 모든 leaf 노드를 미리 삽입해두는 것이 아니라 아래처럼 순차적으로 max(LIS(1, i))의 계산과 삽입을 번갈아 수행합니다.
26+
nums[i]의 크기가 작은 것부터 순서대로, "max(LIS(1, j))를 계산하고, leaf를 하나 삽입"하는 과정을 반복합니다.
27+
nums[i]보다 더 큰 값은 아직 인덱스 트리에 삽입되지 않은 상태이기 때문에, 인덱스 트리에서 구간 [1, i-1]의 최대값을 조회하면 nums[j] < num[i]인 j에 대해서만 최대값을 찾게 되므로,
28+
(2)번 과정을 O(logn) 시간에 구할 수 있습니다.
29+
따라서 전체 시간 복잡도는 O(nlogn)이 됩니다.
430
*/
531
class Solution {
632

0 commit comments

Comments
 (0)