|
11 | 11 | # solution |
12 | 12 | 이 문제는 DP로 접근했습니다. |
13 | 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) |
| 14 | +LIS(0, x)를 범위 [0, x] 내의 LIS(단, nums[x]를 반드시 포함)의 길이라고 정의하겠습니다. - (1) |
| 15 | +1 <= j < i 인 모든 j에 한 LIS(1, j)를 알고 있다면, LIS(0, i)는 아래와 같이 구할 수 있습니다. |
| 16 | +LIS(0, i) = max(LIS(0, j)) (단, j는 0 <= j < i 이고, nums[j] < nums[i]) - (2) |
17 | 17 |
|
18 | | -max(LIS(1, j))를 구할 때, 모든 j에 대해 탐색한다면, 전체 시간 복잡도는 O(n^2)가 되기 때문에, 시간 복잡도를 줄일 필요가 있습니다. |
| 18 | +max(LIS(0, j))를 구할 때, 모든 j에 대해 탐색한다면, 전체 시간 복잡도는 O(n^2)가 되기 때문에, 시간 복잡도를 줄일 필요가 있습니다. |
19 | 19 | 이 탐색 과정을 줄이기 위해, 아래의 사고 과정을 거쳤습니다. |
20 | 20 |
|
21 | 21 | 어떤 범위 내의 가장 큰 값을 O(logn) 시간에 구하기 위한 자료구조로, 인덱스 트리(혹은 세그먼트 트리)를 사용합니다. |
22 | | -(이 인덱스 트리의 x번째 leaf 노드에는 LIS(1, x) 값을 저장하고, internal 노드에는 자식 노드들 중 가장 큰 값을 저장합니다.) |
| 22 | +(이 인덱스 트리의 x번째 leaf 노드에는 LIS(0, x) 값을 저장하고, internal 노드에는 자식 노드들 중 가장 큰 값을 저장합니다.) |
23 | 23 |
|
24 | 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에 대해서만 최대값을 찾게 되므로, |
| 25 | +그러기 위해서, 인덱스 트리에 모든 leaf 노드를 미리 삽입해두는 것이 아니라 아래처럼 순차적으로 max(LIS(0, i))의 계산과 삽입을 번갈아 수행합니다. |
| 26 | +nums[i]의 크기가 작은 것부터 순서대로, "max(LIS(0, j))를 계산하고, leaf를 하나 삽입"하는 과정을 반복합니다. |
| 27 | +nums[i]보다 더 큰 값은 아직 인덱스 트리에 삽입되지 않은 상태이기 때문에, 인덱스 트리에서 구간 [0, i-1]의 최대값을 조회하면 nums[j] < num[i]인 j에 대해서만 최대값을 찾게 되므로, |
28 | 28 | (2)번 과정을 O(logn) 시간에 구할 수 있습니다. |
29 | 29 | 따라서 전체 시간 복잡도는 O(nlogn)이 됩니다. |
30 | 30 | */ |
|
0 commit comments