[PS] 99ํด๋ฝ ์ฝํ ์คํฐ๋ 29์ผ์ฐจ TIL (Longest Increasing Subsequence)
ํ๊ทธ: 99ํด๋ฝ, PS, TIL, ์ด๋ถํ์, ์ฝ๋ฉํ ์คํธ์ค๋น, ํญํด99
์นดํ ๊ณ ๋ฆฌ: PS
๋ฌธ์
์ค๋ช
์ด๋ค ์์ด์ด ์ฃผ์ด์ง๊ณ ์์ด ๋ด์์ ์๋ฅผ ๋ช๊ฐ ๋ฝ๋๋ค๊ณ ํ์ ๋, ๊ฐ์ฅ ๊ธด ์ฆ๊ฐํ๋ ๋ถ๋ถ์์ด(LIS)์ ๊ธธ์ด๋ฅผ ๋ฐํํ๋ ๋ฌธ์
ํ์ด (DP)
dp[i]
๋ nums[i]
๋ฅผ ๋ง์ง๋ง ์์๋ก ํ๋ LIS ์ ๊ธธ์ด๋ฅผ ๋ํ๋ธ๋ค.
์ ์ฒด ๋ฐฐ์ด์ ์ํํ๋ฉด์ ํ์ฌ ์ธ๋ฑ์ค๊น์ง nums[j] < nums[i]
์ธ ๊ฒฝ์ฐ๊ฐ ์๋ค๋ ๊ฒ์ LIS ๊ฐ ๋ ์ ์๋ ์กฐ๊ฑด์ด๊ธฐ ๋๋ฌธ์
dp[i]
๋ฅผ ๋ค์ ๊ธฐ์ค ์ค ๋ ๊ธด ๊ธธ์ด๋ก ๊ฐฑ์ ํด ์ค๋ค.
- j ์ธ๋ฑ์ค ๊น์ง ๊ณ์ฐํ LIS ๋ง์ง๋ง์ nums[i] ๋ฅผ ์ถ๊ฐํ ๊ธธ์ด (dp[j] + 1)
- ๊ธฐ์กด์ dp[i] ๊ฐ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
int maxLen = 1;
for (int i = 1; i < nums.length; i++) {
for (int j = 0; j < i; j++) { // ํ์ฌ ์ธ๋ฑ์ค(i) ์ ๊น์ง ๊ฒ์ฌ
if (nums[j] < nums[i]) { // ๊ตฌ๊ฐ ๋ด์์ ํ์ฌ ์ธ๋ฑ์ค ๊ฐ(arr[i]) ๋ณด๋ค ์์ผ๋ฉด LIS ์กฐ๊ฑด ์ฑ๋ฆฝ
dp[i] = Math.max(dp[i], dp[j] + 1); // dp[i] ๊ฐ ๊ฐฑ์
}
}
maxLen = Math.max(maxLen, dp[i]); // ๊ธฐ์กด LIS ๋ณด๋ค ๊ธธ๋ฉด ๊ฐฑ์
}
return maxLen;
}
}
์ ์ฒด ๋ฐฐ์ด์ ์์ฐจ์ ์ผ๋ก ์ํํ๋ฉด์ ์ง์ ์ธ๋ฑ์ค ๋น๊ต๋ฅผ ํ๊ธฐ ๋๋ฌธ์ O(n^2) ์ ์๊ฐ๋ณต์ก๋๊ฐ ๋๋ค.
ํ์ด (์ด๋ถํ์)
LIS ๋ฌธ์ ๋ฅผ ์ด๋ถ ํ์์ผ๋ก ํ๊ฒ๋๋ฉด O(n log n) ์ ์๊ฐ๋ณต์ก๋๋ก ํด๊ฒฐํ ์ ์๋ค. ์ DP ๋ฐฉ์์์ dp[i] ๋ฅผ LIS ์ ๊ธธ์ด๋ก ์ ์ํ์๋๋ฐ, ์ด๋ถ ํ์ ๋ฐฉ์์์ lis ๋ฐฐ์ด์ ํ์ฌ๊น์ง ์ฐพ์ LIS ๊ฐ ์ ์ฅ๋์ด ์๋ค.
์๋ฐ์์ Arrays.binarySearch()
๋ฅผ ํตํด ์ด๋ถํ์์ ์ํ ํ ์ ์๋ค. ์ฒซ๋ฒ์งธ ์ธ์๋ก ๊ฐ์ ์ฐพ๊ณ ์ํ๋ ๋ฐฐ์ด์ ๋๊ฒจ์ฃผ๊ณ ์์๋๋ก fromIndex, toIndex, key ๋ฅผ ๋๊ฒจ์ค๋ค.
key ๊ฐ์ lis ์์ ์ฐพ๊ฒ๋๋ฉด ์ฐพ์ ์์น ์ธ๋ฑ์ค๋ฅผ ๋ฐํํ๋ค.
๋ง์ฝ ๋ชป์ฐพ๊ฒ ๋๋ฉด -(insertion point) -1
๊ฐ์ ๋ฐํํ๋๋ฐ
์๋ฅผ ๋ค์ด ์ฝ์
์ง์ ์ด index 2
์ธ ๊ฒฝ์ฐ Arrays.binarySearch()
๋ -3 ์ ๋ฐํํ๋ค.
1
2
int[] arr = {1, 3, 5, 7};
int pos = Arrays.binarySearch(arr, 4); // returns -3
lis ์ ์ฝ์
์์น ๊ทธ๋๋ก ์ ์ฅํ๊ธฐ ์ํด -(pos + 1)
๋ฅผ ํ๊ฒ๋๋ฉด -(-3 + 1) = 2
๊ฐ ๋๋ค. ์ ์์์ฒ๋ผ 4๋ 2๋ฒ์งธ ์ธ๋ฑ์ค์ ๋ค์ด๊ฐ์ผ ํจ์ ์ ์ ์๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public int lengthOfLIS(int[] nums) {
int[] lis = new int[nums.length];
int length = 0; // ํ์ฌ lis ๋ฐฐ์ด์ ์ ํจ ๊ธธ์ด
for (int num : nums) {
int pos = Arrays.binarySearch(lis, 0, length, num);
if (pos < 0) {
pos = -(pos + 1); // lis ๋ฐฐ์ด์ ์ฝ์
ํ ์์น ๊ณ์ฐ
}
lis[pos] = num;
if (pos == length) {
length++;
}
}
return length;
}
}
๋ง์ฝ ํ์ฌ lis ๋ฐฐ์ด์ [0, 1, 3]
์ด ๋ค์ด์๋ ์ํ์์ num = 2
์ด๋ฉด pos ๋ -3 ์ด ๋๊ณ , -(pos + 1) = 2
๊ฐ ๋๋ค.
lis ๋ฐฐ์ด์ [0, 1, 2]
๊ฐ ๋์ด 3์ด 2๋ก ๋์ฒด๋๋ค. ์ฆ, lis ๋ฐฐ์ด์ ๊ณ์ํด์ ์ค๋ฆ์ฐจ์์ผ๋ก ๊ฐ์ด ๋ค์ด๊ฐ๊ฒ ๋๋ค.
length
๋ณ์๋ lis ๋ฐฐ์ด์ ๊ฐ์ด ํ๋์ฉ ์ถ๊ฐ๋ ๋๋ง๋ค ๋์ด๋๊ฒ ๋๋ค. ์ dp ๋ฐฉ์๊ณผ์ ์ฐจ์ด์ ์ด๋ผ๊ณ ํ๋ค๋ฉด dp ๋ฐฉ์์ ๋ถ๋ถ ์์ด ์์ฒด์๋ ๊ด์ฌ ์๊ณ ๊ทธ ์๊ฐ ์๊ฐ์ LIS ๊ธธ์ด๋ง์ ์ถ์ ํ๊ณ ์๋ค๋ฉด, ์ด๋ถํ์ ๋ฐฉ์์ ์ค์ ๋ก LIS ๋ฅผ ๊ตฌ์ฑํด ๊ฐ๋ค๋ ์ ์ด ๋ค๋ฅด๋ค.
๋๊ธ๋จ๊ธฐ๊ธฐ