[Leetcode, Python] 300. Longest Increasing Subsequence 풀이

2026. 7. 31. 14:56·Algorithm/Algorithm

이 글은 Velog에서 이전한 글입니다. Velog 원문 보기

Leetcode 300번 문제

"오름차순 수열의 최대 길이"를 찾는 문제라고 생각하고 풀었다.
첫번째 시도

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        N = len(nums)
        dp = [1]*N # dp[i] = index i까지의 최댓값

        for i in range(1, N):
            if nums[i] < nums[i-1]:
                dp[i] = dp[i-1] # index i의 값이 i-1의 값보다 작다면 증가하는 수열에 포함되지 않음
            elif nums[i] > nums[i-1]:
                dp[i] = dp[i-1] + 1 # 증가하는 수열에 포함

        return max(dp)

처음에는 DP(다이나믹 프로그래밍)을 활용해서

  1. nums의 i index의 값이 i-1 index의 값보다 작다면 증가하는 수열에 포함되지 않는다.
  2. dp[i-1]는 index i-1까지의 최대 수열 길이를 갖기 때문에 dp[i] = dp[i-1]로 최대 수열 길이를 유지한다.
  3. nums의 i index의 값이 i-1 index의 값보다 크다면 증가하는 수열에 포함한다. dp[i] = dp[i-1]+1 최대 수열 길이에 +1을 한다.

이러한 사고 흐름으로 코드를 구현했다.
그러나 24번째 tastcase에서 실패했다.

실패 테스트 케이스
input: nums = [4,10,4,3,8,9]
output: Exptected: 3

내가 구현한 코드의 흐름으로 실패 테스트 케이스를 실행하면
dp = [1,2,2,2,3,4] -> 즉, Output으로 4가 나온다.

현재 코드의 문제점
현재 방식은 '인접한 두 원소'만 비교하고 있어서, 전체 증가 수열 중에서 가장 긴 걸 찾지 못한다.

for i in range(1, N):
    if nums[i] < nums[i-1]:
        dp[i] = dp[i-1]
    elif nums[i] > nums[i-1]:
        dp[i] = dp[i-1] + 1

해당 루프는 i와 i-1만 비교하고 있다.
문제를 해결하려면 nums[0] ~ nums[i-1]까지 모든 이전 원소들 중에서 nums[i]보다 작은 값들을 고려해야 한다.

수정 코드

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        N = len(nums)
        dp = [1]*N # dp[i] = index i까지의 최댓값

        for i in range(1, N):
            for j in range(i):
                if nums[j] < nums[i]:
                    dp[i] = max(dp[i], dp[j]+1)
        return max(dp)
  1. dp[i]는 nums[i]를 마지막으로 하는 최장 증가 수열의 길이이다.
  2. nums[0] ~ nums[i-1] 중에서, nums[j] < nums[i]인 모든 j를 찾는다.
  3. j들 중 가장 긴 수열을 고르고 nums[i]를 붙인다.

코드는 통과했다. 하지만 현재 코드는 O(n^2)의 시간 복잡도를 갖는다.

O(nlogn) 코드

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        dp = []

        def binary_search(target): # 이진 탐색
            left, right = 0, len(dp)-1
            while left <= right:
                mid = (left+right)//2
                if dp[mid] < target:
                    left = mid + 1
                else:
                    right = mid - 1
            return left

        for num in nums:
            idx = binary_search(num)
            if idx == len(dp):
                dp.append(num)
            else:
                dp[idx] = num

        return len(dp)
  1. 빈 dp 배열을 생성한다.
  • 실제 LIS를 저장하지 않고, 각 길이에 해당하는 최솟값의 후보들만 저장한다.
  1. nums 배열을 순회한다.
  2. 현재 수 num을 dp에서 이진 탐색으로 삽입할 위치 idx를 찾는다.
  • dp[idx-1] < num <= dp[idx]를 만족하는 위치가 된다.
  1. 찾은 위치 idx가 dp의 끝이라면 → num은 가장 긴 수열의 다음 수가 될 수 있으므로 추가
  • 그렇지 않다면 → 기존 값을 num으로 덮어씌워서 더 나은 후보로 교체
  1. 전체 과정이 끝나면 dp의 길이가 LIS의 길이=정답이다.

요약: nums 순회 → 이진 탐색으로 위치 찾기 → dp에 삽입 or 대체 → dp 길이 = 정답

LIS: Longest increasing Subsequence, 최장 증가 부분 수열

'Algorithm > Algorithm' 카테고리의 다른 글

[BOJ, Python] 2252번_줄 세우기 With 위상 정렬  (0) 2026.08.02
[BOJ, Python] 1197번_최소 스패닝 트리  (0) 2026.08.02
[BOJ, Python] 백준 NZEC(Non-Zero Exit Code) 오류  (0) 2026.07.31
[BOJ, Python] 1699번_제곱수의 합  (0) 2026.07.31
✏️ [Algorithm] itertools 라이브러리에 대해서  (0) 2026.07.30
'Algorithm/Algorithm' 카테고리의 다른 글
  • [BOJ, Python] 2252번_줄 세우기 With 위상 정렬
  • [BOJ, Python] 1197번_최소 스패닝 트리
  • [BOJ, Python] 백준 NZEC(Non-Zero Exit Code) 오류
  • [BOJ, Python] 1699번_제곱수의 합
pp8817
pp8817
공부한 내용, 개발 관련 지식, 트러블 슈팅 등을 기록합니다. 이전 블로그: https://velog.io/@pp8817/posts
  • pp8817
    끄적이는 개발 log
    pp8817
  • 전체
    오늘
    어제
    • 분류 전체보기 (273)
      • Project (71)
        • 척척학사 (29)
        • Book (23)
        • Saynow (3)
        • YAPP 27기 (4)
        • 나의 작은 프로젝트 (10)
        • Landit (2)
      • Backend (88)
        • Spring (13)
        • Spring MVC (13)
        • Spring Security (4)
        • JPA (26)
        • Database (19)
        • HTTP·Web (13)
        • Architecture (0)
      • Language·CS (59)
        • Java·Kotlin (5)
        • CS Interview (17)
        • Backend Interview (5)
        • Concepts (32)
      • Algorithm (25)
        • Algorithm (24)
        • 소마 알고리즘 스터디 (1)
      • Infra (8)
      • Troubleshooting (11)
      • Retrospective (6)
      • Etc (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    CS Interview
    HTTP WEB 기본 지식
    Book
    BOJ
    object
    척척학사
    OS
    java
    Python
    Algorithm
    나의 작은 프로젝트
    Spring
    interview
    jpa
    게시판
    개념 정리!
    Spring MVC
    Project
    http
    트러블슈팅
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
pp8817
[Leetcode, Python] 300. Longest Increasing Subsequence 풀이
상단으로

티스토리툴바