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

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.

🏷️ 알고리즘 패턴 분석

construct-binary-tree-from-preorder-and-inorder-traversal/yuseok89.py
# TC: O(N)
# SC: O(N)
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def buildTree(self, preorder: list[int], inorder: list[int]) -> TreeNode | None:

        inorder_map = {val: idx for idx, val in enumerate(inorder)}
        preorder_idx = 0

        def build(left: int, right: int) -> TreeNode | None:
            nonlocal preorder_idx

            if left > right:
                return None

            root_val = preorder[preorder_idx]
            root = TreeNode(root_val)
            preorder_idx += 1

            mid = inorder_map[root_val]

            root.left = build(left, mid - 1)
            root.right = build(mid + 1, right)

            return root

        return build(0, len(inorder) - 1)
  • 패턴: Divide and Conquer, Hash Map / Hash Set
  • 설명: 전위(order)와 중위(inorder) 배열을 이용해 재귀적으로 트리의 서브트리를 구성한다. 중위 배열의 위치를 해시 맵으로 빠르게 찾고, 재귀적으로 각 부분 트리를 분할해 트리를 구축한다.

📊 시간/공간 복잡도 분석

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

피드백: 중위순회 인덱스 맵을 이용해 각 재귀에서 상위 노드의 위치를 상수시간에 찾는다. 재귀 깊이는 트리의 높이에 비례한다.

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# TC: O(N)
# SC: O(N)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def buildTree(self, preorder: list[int], inorder: list[int]) -> TreeNode | None:

inorder_map = {val: idx for idx, val in enumerate(inorder)}
preorder_idx = 0

def build(left: int, right: int) -> TreeNode | None:
nonlocal preorder_idx

if left > right:
return None

root_val = preorder[preorder_idx]
root = TreeNode(root_val)
preorder_idx += 1

mid = inorder_map[root_val]

root.left = build(left, mid - 1)
root.right = build(mid + 1, right)

return root

return build(0, len(inorder) - 1)

29 changes: 29 additions & 0 deletions longest-palindromic-substring/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-palindromic-substring/yuseok89.py
# TC: O(N)
# SC: O(1)
class Solution:
    def longestPalindrome(self, s: str) -> str:

        n = len(s)
        max_len, left = 1, 0

        for mid in range(n):
            l, r = mid, mid

            while l >= 0 and r < n and s[l] == s[r]:
                l -= 1
                r += 1

            if max_len < r - l - 1:
                max_len, left = r - l - 1, l + 1

            l, r = mid, mid + 1

            while l >= 0 and r < n and s[l] == s[r]:
                l -= 1
                r += 1

            if max_len < r - l - 1:
                max_len, left = r - l - 1, l + 1

        return s[left:left + max_len]
  • 패턴: Greedy, Two Pointers, Binary Search, Dynamic Programming, Monotonic Stack, Hash Map / Hash Set, Sliding Window, DFS, BFS, Backtracking, Divide and Conquer, Union Find, Trie, Bit Manipulation, Heap / Priority Queue
  • 설명: 주어진 코드가 팰린드롬 부분 문자열을 중심 확장으로 찾는 방식으로, 각 중심에서 좌우로 확장하는 두 포인터 접근이 핵심이다. 이를 통해 선형 시간과 상수 공간 근사로 최장 팰린드롬 길이를 찾는다.

📊 시간/공간 복잡도 분석

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

피드백: 각 중심에 대해 양쪽으로 확장하며 최장 팰린드롱 문자열을 찾는다. 추가적인 자료구조 없이 상수 공간으로 구현 가능하다.

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

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-palindromic-substring/yuseok89.py
# TC: O(N^2)
# SC: O(1)
class Solution:
    def longestPalindrome(self, s: str) -> str:

        n = len(s)
        max_len, left = 1, 0

        for mid in range(n):
            l, r = mid, mid

            while l >= 0 and r < n and s[l] == s[r]:
                l -= 1
                r += 1

            if max_len < r - l - 1:
                max_len, left = r - l - 1, l + 1

            l, r = mid, mid + 1

            while l >= 0 and r < n and s[l] == s[r]:
                l -= 1
                r += 1

            if max_len < r - l - 1:
                max_len, left = r - l - 1, l + 1

        return s[left:left + max_len]
  • 패턴: Two Pointers, Sliding Window, Dynamic Programming
  • 설명: 가운데를 기준으로 좌우로 확장하는 방식으로 팰린드롬을 찾는 패턴이며, 부분 문자열의 길이를 갱신하기 위해 양 쪽 포인터를 이동시키는 슬라이딩/투 포인터 기법을 사용합니다. DP의 직접적인 테이블은 없지만, 부분 문제를 확장하는 아이디어가 비슷하게 적용됩니다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
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,29 @@
# TC: O(N^2)
# SC: O(1)
class Solution:
def longestPalindrome(self, s: str) -> str:

n = len(s)
max_len, left = 1, 0

for mid in range(n):
l, r = mid, mid

while l >= 0 and r < n and s[l] == s[r]:
l -= 1
r += 1

if max_len < r - l - 1:
max_len, left = r - l - 1, l + 1

l, r = mid, mid + 1

while l >= 0 and r < n and s[l] == s[r]:
l -= 1
r += 1

if max_len < r - l - 1:
max_len, left = r - l - 1, l + 1

return s[left:left + max_len]

25 changes: 25 additions & 0 deletions rotate-image/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.

🏷️ 알고리즘 패턴 분석

rotate-image/yuseok89.py
# TC: O(N^2)
# SC: O(1)
class Solution:
    def rotate(self, matrix: list[list[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """

        n = len(matrix)

        for k in range(0, n // 2):

            y11, x11 = k, k
            y12, x12 = k, n - 1 - k
            y21, x21 = n - 1 - k, k
            y22, x22 = n - 1 - k, n - 1 - k

            for _ in range(0, n - 1 - k * 2):
                matrix[y11][x11], matrix[y21][x21], matrix[y22][x22], matrix[y12][x12] = matrix[y21][x21], matrix[y22][x22], matrix[y12][x12], matrix[y11][x11]

                x11 += 1
                y12 += 1
                x22 -= 1
                y21 -= 1
  • 패턴: Two Pointers, Greedy, Divide and Conquer
  • 설명: 이미지 회전은 4개의 원소를 하나의 원소로 순환시키며 in-place로 교환하는 패턴으로, 각 위치의 원소를 시계방향으로 이동시키는 두 포인터의 동작과 여러 원소를 한 번에 처리하는 구조를 가짐. 직접 원소를 교환하는 방식은 투포인터의 조합으로 구현되며, 전체를 한 루프에서 순환시키는 점에서 그리드의 짝-홀 경계에서의 처리도 포함

📊 시간/공간 복잡도 분석

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

피드백: 외곽 레이어에서 내부 레이어로 차례대로 4개 원소를 순환시키며 제자리에서 회전한다. 추가 공간 없이 in-place 로 동작한다.

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# TC: O(N^2)
# SC: O(1)
class Solution:
def rotate(self, matrix: list[list[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""

n = len(matrix)

for k in range(0, n // 2):

y11, x11 = k, k
y12, x12 = k, n - 1 - k
y21, x21 = n - 1 - k, k
y22, x22 = n - 1 - k, n - 1 - k

for _ in range(0, n - 1 - k * 2):
matrix[y11][x11], matrix[y21][x21], matrix[y22][x22], matrix[y12][x12] = matrix[y21][x21], matrix[y22][x22], matrix[y12][x12], matrix[y11][x11]

x11 += 1
y12 += 1
x22 -= 1
y21 -= 1

42 changes: 42 additions & 0 deletions subtree-of-another-tree/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.

🏷️ 알고리즘 패턴 분석

subtree-of-another-tree/yuseok89.py
# TC: O(N)
# SC: O(N)
class Solution:
    def isSubtree(self, root: TreeNode | None, subRoot: TreeNode | None) -> bool:

        def isSameTree(p, q):
            if not p and not q:
                return True
            if not p or not q or p.val != q.val:
                return False

            return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)

        def get_size(node):
            if not node:
                return 0
            return 1 + get_size(node.left) + get_size(node.right)

        target_size = get_size(subRoot)
        is_match = False

        def check_tree(node):
            nonlocal is_match

            if not node or is_match:
                return 0

            left_size = check_tree(node.left)
            right_size = check_tree(node.right)

            current_size = 1 + left_size + right_size

            if current_size == target_size:
                if isSameTree(node, subRoot):
                    is_match = True

            return current_size

        check_tree(root)

        return is_match
  • 패턴: Depth-First Search, Binary Search
  • 설명: 두 트리를 순회하며 서브트리를 판단하는 과정에서 DFS로 트리 전체를 탐색하고, 각 노드에서 서브트리 형태를 isSameTree로 비교하는 패턴이 드러난다. 또 트리의 크기를 비교하는 과정에서 가지치기 성격의 비교를 활용한다.

📊 시간/공간 복잡도 분석

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

피드백: 모든 노드에 대해 서브트리 매칭을 시도하므로 최악의 경우 두 트리의 크기 비례에 따른 시간 복잡도가 발생한다. 공간은 재귀 스택의 깊이에 비례한다.

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# TC: O(N)
# SC: O(N)
class Solution:
def isSubtree(self, root: TreeNode | None, subRoot: TreeNode | None) -> bool:

def isSameTree(p, q):
if not p and not q:
return True
if not p or not q or p.val != q.val:
return False

return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)

def get_size(node):
if not node:
return 0
return 1 + get_size(node.left) + get_size(node.right)

target_size = get_size(subRoot)
is_match = False

def check_tree(node):
nonlocal is_match

if not node or is_match:
return 0

left_size = check_tree(node.left)
right_size = check_tree(node.right)

current_size = 1 + left_size + right_size

if current_size == target_size:
if isSameTree(node, subRoot):
is_match = True

return current_size

check_tree(root)
Comment on lines +3 to +39

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.

같은 트리인 경우 가지치기로 처리하신 부분이 인상깊네요!
풀이 잘 보았습니다!


return is_match

Loading