diff --git a/longest-common-subsequence/haklee.py b/longest-common-subsequence/haklee.py index c7dd2502b..2d384d929 100644 --- a/longest-common-subsequence/haklee.py +++ b/longest-common-subsequence/haklee.py @@ -29,7 +29,13 @@ SC: - 첫 번째 문자열의 앞 i글자로 만든 문자열과 두 번째 문자열의 앞 j글자로 만든 문자열의 lcs의 길이를 관리. -- O(m * n) +- 그런데 아이디어에 제시된 점화식을 보면 i, j값에 대한 전체 배열을 저장할 필요 없이 i=k일때 + 값을 구하려 한다면 i=k-1일때 구한 lcs값만 알고 있으면 충분하다. +- 즉, 배열은 현재 구하고자 하는 i값에 대한 j개의 아이템과 직전에 구한 j개의 아이템만 저장하면 + 충분하다. 즉, text2의 길이인 O(n)이라고 볼 수 있다. +- 그런데 만약 text2의 길이가 text1보다 길면 이 둘을 바꿔치기해서 위의 공간복잡도를 O(m)이라고 + 봐도 아이디어 자체는 똑같이 작동하지 않는가? +- 즉, O(min(m, n)) TC: - dp 배열을 채우는 데에 마지막 문자가 같을 경우 단순 덧셈, 다를 경우 두 값 비교. 둘 다 O(1). @@ -39,14 +45,20 @@ class Solution: def longestCommonSubsequence(self, text1: str, text2: str) -> int: - dp = [[0 for _ in range(len(text2) + 1)] for _ in range(len(text1) + 1)] + if len(text2) > len(text1): + # 이 최적화까지 해주면 사용하는 메모리 크기가 많이 줄어들 수 있다. + text1, text2 = text2, text1 + + dp = [[0 for _ in range(len(text2) + 1)] for _ in range(2)] for i in range(1, len(text1) + 1): + i_prev = (i + 1) % 2 + i_cur = i % 2 for j in range(1, len(text2) + 1): - dp[i][j] = ( - dp[i - 1][j - 1] + 1 + dp[i_cur][j] = ( + dp[i_prev][j - 1] + 1 if text1[i - 1] == text2[j - 1] - else max(dp[i - 1][j], dp[i][j - 1]) + else max(dp[i_prev][j], dp[i_cur][j - 1]) ) - return dp[-1][-1] + return dp[i_cur][-1] diff --git a/sum-of-two-integers/haklee.py b/sum-of-two-integers/haklee.py index ec4fc1787..f7b7dde15 100644 --- a/sum-of-two-integers/haklee.py +++ b/sum-of-two-integers/haklee.py @@ -116,7 +116,7 @@ def getSum(self, a: int, b: int) -> int: b의 범위가 제한되어 있어서 접근 불가능한, 즉, 필요 없는 숫자들이라고 보면 된다. SC: -- O(n^2). 정확히는, (2*n+1)^2 개의 정수를 배열에 저장한다. +- 코드 참조. O(n). TC: - 인덱스를 통해 바로 접근. O(1). @@ -127,7 +127,7 @@ class Solution: def getSum(self, a: int, b: int) -> int: x = list(range(0, 2001)) x.extend(list(range(-2000, 0))) - v = x * 2 - s = list(range(0, 4001)) - e = list(range(4001, 8002)) + v = x * 2 # SC: O(n) + s = list(range(0, 4001)) # SC: O(n) + e = list(range(4001, 8002)) # SC: O(n) return v[s[a] : e[a]][b]