|
| 1 | +class Solution: |
| 2 | + def lengthOfLIS(self, nums: List[int]) -> int: |
| 3 | + n = len(nums) |
| 4 | + # dp[i] = i번째 원소로 끝나는 LIS의 길이 |
| 5 | + dp = [1] * n # 최소 자기 자신 1개 |
| 6 | + |
| 7 | + for i in range(1, n): |
| 8 | + for j in range(i): |
| 9 | + # nums[j] < nums[i]이면, j로 끝나는 LIS에 i를 붙일 수 있음 |
| 10 | + if nums[j] < nums[i]: |
| 11 | + dp[i] = max(dp[i], dp[j] + 1) |
| 12 | + |
| 13 | + return max(dp) |
| 14 | + |
| 15 | +""" |
| 16 | +================================================================================ |
| 17 | +풀이 과정 |
| 18 | +================================================================================ |
| 19 | +
|
| 20 | +[1차 시도] 투포인터? |
| 21 | +──────────────────────────────────────────────────────────────────────────────── |
| 22 | +1. 처음엔 투포인터로 풀 수 있을 것 같았음 |
| 23 | +
|
| 24 | +2. 근데 생각해보니 Subsequence는 연속된 원소가 아니어도 됨 |
| 25 | + - Subarray(부분 배열): 연속 필수 → 투포인터 가능 |
| 26 | + - Subsequence(부분 수열): 연속 안 해도 됨 → 투포인터 불가 |
| 27 | +
|
| 28 | +3. 예시: [10, 9, 2, 5, 3, 7, 101, 18] |
| 29 | + - LIS = [2, 3, 7, 101] (인덱스 2, 4, 5, 6) |
| 30 | + - 연속되지 않은 위치에서 선택해야 함 → DP로 접근 |
| 31 | +
|
| 32 | +──────────────────────────────────────────────────────────────────────────────── |
| 33 | +[2차 시도] DP |
| 34 | +──────────────────────────────────────────────────────────────────────────────── |
| 35 | +4. 정의: dp[i] = nums[i]로 끝나는 LIS의 길이 |
| 36 | +
|
| 37 | +5. 점화식: |
| 38 | + dp[i] = max(dp[j] + 1) for all j < i where nums[j] < nums[i] |
| 39 | +
|
| 40 | + 해석: i 이전의 모든 j를 보면서 |
| 41 | + nums[j] < nums[i]이면 (증가 조건 만족) |
| 42 | + dp[j]에 나를 붙일 수 있으므로 dp[j] + 1 |
| 43 | +
|
| 44 | +6. 동작 예시: nums = [10, 9, 2, 5, 3, 7, 101, 18] |
| 45 | +
|
| 46 | + 초기: dp = [1, 1, 1, 1, 1, 1, 1, 1] |
| 47 | +
|
| 48 | + i=0 (10): 이전 원소 없음 → dp[0] = 1 |
| 49 | + i=1 (9): 10 > 9 (X) → dp[1] = 1 |
| 50 | + i=2 (2): 10 > 2 (X), 9 > 2 (X) → dp[2] = 1 |
| 51 | + i=3 (5): 2 < 5 (O) → dp[3] = dp[2] + 1 = 2 |
| 52 | + i=4 (3): 2 < 3 (O) → dp[4] = dp[2] + 1 = 2 |
| 53 | + i=5 (7): 2 < 7 (O) → dp[5] = 2 |
| 54 | + 5 < 7 (O) → dp[5] = max(2, dp[3]+1) = 3 |
| 55 | + 3 < 7 (O) → dp[5] = max(3, dp[4]+1) = 3 |
| 56 | + i=6 (101): 7 < 101 (O) → dp[6] = dp[5] + 1 = 4 |
| 57 | + i=7 (18): 7 < 18 (O) → dp[7] = dp[5] + 1 = 4 |
| 58 | +
|
| 59 | + 최종: dp = [1, 1, 1, 2, 2, 3, 4, 4] |
| 60 | + 답: max(dp) = 4 |
| 61 | +
|
| 62 | +7. 시간복잡도: O(n²) - 이중 for문 |
| 63 | +8. 공간복잡도: O(n) - dp 배열 |
| 64 | +""" |
0 commit comments