Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions clone-graph/yuseok89.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

clone-graph/yuseok89.py
# TC: O(N)
# SC: O(N)
"""
# Definition for a Node.
class Node:
    def __init__(self, val = 0, neighbors = None):
        self.val = val
        self.neighbors = neighbors if neighbors is not None else []
"""

from typing import Optional
class Solution:
    def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:

        visited = {}

        def rec(node: Optional['Node']) -> Optional['Node']:

            if not node:
                return None

            if node.val in visited:
                return visited[node.val]

            return_val = Node(node.val)
            visited[node.val] = return_val

            for neighbor in node.neighbors:
                cloned = rec(neighbor)

                if cloned:
                    return_val.neighbors.append(cloned)

            return return_val

        return rec(node)
  • 패턴: Depth-First Search, Hash Map / Hash Set, Backtracking
  • 설명: 그래프의 연결 노드를 재귀적으로 순회하며 각 노드를 복제하고, 방문 맵으로 중복 복제를 방지한다. 재귀 DFS를 이용해 이웃 노드를 탐색하고, 중복 방문 여부를 해시 맵으로 관리한다.

📊 시간/공간 복잡도 분석

복잡도
Time O(N + E)
Space O(N)

피드백: 노드의 val를 키로 사용해 방문 여부를 판단하지만, 노드 간 값이 같아도 서로 다른 노드를 구별해야 할 수 있으니 id 기반 매핑이 더 안정적일 수 있습니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# TC: O(N)
# SC: O(N)
"""
# Definition for a Node.
class Node:
def __init__(self, val = 0, neighbors = None):
self.val = val
self.neighbors = neighbors if neighbors is not None else []
"""

from typing import Optional
class Solution:
def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:

visited = {}

def rec(node: Optional['Node']) -> Optional['Node']:

if not node:
return None

if node.val in visited:
return visited[node.val]

return_val = Node(node.val)
visited[node.val] = return_val

for neighbor in node.neighbors:
cloned = rec(neighbor)

if cloned:
return_val.neighbors.append(cloned)

return return_val

return rec(node)

22 changes: 22 additions & 0 deletions longest-common-subsequence/yuseok89.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

longest-common-subsequence/yuseok89.py
# TC: O(N*M)
# SC: O(N*M)
class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:

        n = len(text1)
        m = len(text2)
        dp = [[0 for _ in range(m + 1)] for _ in range(n + 1)]

        for i in range(n):
            for j in range(m):
                if text1[i] == text2[j]:
                    dp[i + 1][j + 1] = dp[i][j] + 1
                else:
                    dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j])

        return dp[n][m]
  • 패턴: Dynamic Programming
  • 설명: 두 문자열의 부분수열 공통 길이를 구하는 문제로, 이중 루프를 통해 부분문제의 해를 저장하는 표 형태의 DP 테이블을 사용합니다. 부분문제의 해를 바탕으로 최댓값을 점진적으로 구성합니다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(N*M) O(n * m)
Space O(N*M) O(n * m)

피드백: 2D DP 배열을 사용해 모든 부분문자열 조합을 점화식을 통해 계산합니다.

개선 제안: 현재 구현이 적절해 보입니다.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

깔끔한 해결 잘 봤습니다!
공간복잡도의 최적화가 가능하니 시도 해 보시면 좋을것 같아요!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

의견 감사합니다.
더 좋아졌네요

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 이런 방식도 엄청 깔끔하네요, 저도 배우고 갑니다!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

longest-common-subsequence/yuseok89.py
# TC: O(N*M)
# SC: O(N)
class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:

        n = len(text1)
        m = len(text2)
        dp = [[0 for _ in range(m + 1)] for _ in range(2)]

        cur, prev = 1, 0

        for i in range(n):
            for j in range(m):
                if text1[i] == text2[j]:
                    dp[cur][j + 1] = dp[prev][j] + 1
                else:
                    dp[cur][j + 1] = max(dp[prev][j + 1], dp[cur][j])

            cur, prev = prev, cur

        return dp[prev][m]
  • 패턴: Dynamic Programming, Monotonic Stack
  • 설명: 두 문자열의 부분 수열 길이를 DP로 구하며, 이전 행과 현재 행을 번갈아가며 사용하는 공간 최적화 기법은 대표적인 DP 패턴이다. 또한 부분 문제를 재귀적으로 해결하고 최적해를 합쳐 최종 해를 얻는 구조이다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(N*M) O(n * m)
Space O(N) O(m)

피드백: 가로 방향으로 DP를 2행으로만 유지하여 공간을 줄인 풀이다. 매 이터레이션마다 현재 행과 이전 행을 번갈아 갱신한다.

개선 제안: 현재 구현이 적절해 보입니다.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

longest-common-subsequence/yuseok89.py
# TC: O(N*M)
# SC: O(M)
class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:

        n = len(text1)
        m = len(text2)
        dp = [[0 for _ in range(m + 1)] for _ in range(2)]

        cur, prev = 1, 0

        for i in range(n):
            for j in range(m):
                if text1[i] == text2[j]:
                    dp[cur][j + 1] = dp[prev][j] + 1
                else:
                    dp[cur][j + 1] = max(dp[prev][j + 1], dp[cur][j])

            cur, prev = prev, cur

        return dp[prev][m]
  • 패턴: Dynamic Programming, Two Pointers
  • 설명: 두 문자열의 부분수열 길이를 DP로 계산하며, 이중 루프와 인덱스 매핑으로 최댓값을 갱신합니다. 공간을 O(M)으로 축소하기 위해 두 행만 번갈아 갱신하는 점이 특징입니다.

📊 시간/공간 복잡도 분석

ℹ️ 이 파일에는 2가지 풀이가 포함되어 있어 각각 분석합니다.

풀이 1: Solution.longestCommonSubsequence — Time: ✅ O(N*M) → O(n * m) / Space: ✅ O(M) → O(m)
유저 분석 실제 분석 결과
Time O(N*M) O(n * m)
Space O(M) O(m)

피드백: 가로 방향과 세로 방향으로 DP 값을 교차저장하며 공간을 2개 배열로 사용하는 최적화가 적용되어 있다.

개선 제안: 현재 구현이 적절해 보입니다.

풀이 2: Solution.longestCommonSubsequence — Time: ✅ O(N*M) → O(n * m) / Space: ✅ O(M) → O(m)
유저 분석 실제 분석 결과
Time O(N*M) O(n * m)
Space O(M) O(m)

피드백: 반복문에서 두 배열만 사용해 메모리 사용을 줄였고, 인덱스 관리로 올바른 결과를 얻는다.

개선 제안: 현재 구현이 적절해 보입니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# TC: O(N*M)
# SC: O(M)
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:

n = len(text1)
m = len(text2)
dp = [[0 for _ in range(m + 1)] for _ in range(2)]

cur, prev = 1, 0

for i in range(n):
for j in range(m):
if text1[i] == text2[j]:
dp[cur][j + 1] = dp[prev][j] + 1
else:
dp[cur][j + 1] = max(dp[prev][j + 1], dp[cur][j])

cur, prev = prev, cur

return dp[prev][m]

27 changes: 27 additions & 0 deletions longest-repeating-character-replacement/yuseok89.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

longest-repeating-character-replacement/yuseok89.py
# TC: O(N)
# SC: O(K)
class Solution:
    def characterReplacement(self, s: str, k: int) -> int:

        l = 0
        cnt = defaultdict(int)
        m, ans = 0, 0

        for r in range(len(s)):
            c = s[r]
            cnt[c] += 1

            m = max(m, cnt[c])

            while m + k < r - l + 1:
                c = s[l]
                l += 1
                cnt[c] -= 1

                if cnt[c] == m - 1:
                    m = max(cnt.values())

            ans = max(ans, r - l + 1);

        return ans
  • 패턴: Sliding Window, Hash Map / Hash Set
  • 설명: 가변 길이 창(window)을 좌우로 움직이며 최대 부분 문자열을 찾는 슬라이딩 윈도우 패턴과, 문자 빈도 수를 저장하는 해시 맵을 활용하여 조건을 관리합니다. 창 크기를 조정하며 최대 반복 문자 수를 추적하는 구조가 특징적입니다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(N) O(n)
Space O(K) O(1)

피드백: 윈도우의 길이가 증가하는 동안 최대 빈도수를 유지해 조건을 체크합니다.

개선 제안: 현재 구현이 적절해 보입니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# TC: O(N)
# SC: O(K)
class Solution:
def characterReplacement(self, s: str, k: int) -> int:

l = 0
cnt = defaultdict(int)
m, ans = 0, 0

for r in range(len(s)):
c = s[r]
cnt[c] += 1

m = max(m, cnt[c])

while m + k < r - l + 1:
c = s[l]
l += 1
cnt[c] -= 1

if cnt[c] == m - 1:
m = max(cnt.values())

ans = max(ans, r - l + 1);

return ans

31 changes: 31 additions & 0 deletions palindromic-substrings/yuseok89.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

palindromic-substrings/yuseok89.py
# TC: O(N^2)
# SC: O(1)
class Solution:
    def countSubstrings(self, s: str) -> int:

        ans = 0
        n = len(s)

        for center_idx in range(n):

            idx = 0

            while 0 <= center_idx - idx and center_idx + idx < n:
                if s[center_idx - idx] == s[center_idx + idx]:
                    ans = ans + 1
                else:
                    break

                idx += 1

            idx = 0
            while 0 <= center_idx - idx and center_idx + idx + 1< n:
                if s[center_idx - idx] == s[center_idx + idx + 1]:
                    ans = ans + 1
                else:
                    break

                idx += 1

        return ans
  • 패턴: Two Pointers, Monotonic Stack, Dynamic Programming, Divide and Conquer, Hash Map / Hash Set, Greedy, Binary Search, DFS, BFS, Backtracking, Union Find, Trie, Bit Manipulation, Heap / Priority Queue
  • 설명: 주어진 코드는 중심 확장 방법으로 팰린드롬을 확장하며 부분 문자열 수를 센다. 하나의 문자 중심과 이웃 대칭 여부를 체크해 가능한 팰린드롬으로 확장하는 Two Pointers 스타일의 탐색이다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(N^2) O(n^2)
Space O(1) O(1)

피드백: 각 센터에서 좌우로 확장하며 회문 여부를 확인합니다.

개선 제안: 현재 구현이 적절해 보입니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# TC: O(N^2)
# SC: O(1)
class Solution:
def countSubstrings(self, s: str) -> int:

ans = 0
n = len(s)

for center_idx in range(n):

idx = 0

while 0 <= center_idx - idx and center_idx + idx < n:
if s[center_idx - idx] == s[center_idx + idx]:
ans = ans + 1
else:
break

idx += 1

idx = 0
while 0 <= center_idx - idx and center_idx + idx + 1< n:
if s[center_idx - idx] == s[center_idx + idx + 1]:
ans = ans + 1
else:
break

idx += 1

return ans

13 changes: 13 additions & 0 deletions reverse-bits/yuseok89.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

reverse-bits/yuseok89.py
# TC: O(K)
# SC: O(1)
class Solution:
    def reverseBits(self, n: int) -> int:
        ans = 0

        for _ in range(32):
            ans *= 2
            ans += n % 2
            n //= 2

        return ans
  • 패턴: Bit Manipulation
  • 설명: 주어진 코드는 정수의 이진 표현에서 비트를 반전된 순서로 다시 조합하여 역순 이진수를 만듦으로써 비트 조작의 직접적 활용 예시이다. 반복문으로 각 자리 비트를 추출하고 누적해 결과를 구성한다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(K) O(32)
Space O(1) O(1)

피드백: 고정된 비트 길이(32비트) 기준으로 순차적으로 반전한다.

개선 제안: 현재 구현이 적절해 보입니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# TC: O(K)
# SC: O(1)
class Solution:
def reverseBits(self, n: int) -> int:
ans = 0

for _ in range(32):
ans *= 2
ans += n % 2
n //= 2

return ans

Loading