Skip to content

[dolphinflow86] WEEK 15 Solutions - #2878

Merged
parkhojeong merged 5 commits into
DaleStudy:mainfrom
dolphinflow86:main
Oct 4, 2026
Merged

parkhojeong merged 5 commits into
DaleStudy:mainfrom
dolphinflow86:main

Conversation

@dolphinflow86

@dolphinflow86 dolphinflow86 commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

답안 제출 문제

작성자 체크 리스트

  • Projects의 오른쪽 버튼(▼)을 눌러 확장한 뒤, Week를 현재 주차로 설정해주세요.
  • 문제를 모두 푸시면 프로젝트에서 Status를 In Review로 설정해주세요.
  • 코드 검토자 1분 이상으로부터 승인을 받으셨다면 PR을 병합해주세요.

검토자 체크 리스트

Important

본인 답안 제출 뿐만 아니라 다른 분 PR 하나 이상을 반드시 검토를 해주셔야 합니다!

  • 바로 이전에 올라온 PR에 본인을 코드 리뷰어로 추가해주세요.
  • 본인이 검토해야하는 PR의 답안 코드에 피드백을 주세요.
  • 토요일 전까지 PR을 병합할 수 있도록 승인해주세요.

@github-actions github-actions Bot added the py label Oct 2, 2026

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/dolphinflow86.py
# N is the length of the string s.
# TC: O(N^2) - expanding around each of the 2N - 1 possible centers takes up to O(N)
# SC: O(1) - constant auxiliary space tracking the start index and maximum length


class Solution:

    def longestPalindrome(self, s: str) -> str:
        if len(s) <= 1:
            return s

        start, max_len = 0, 0

        def expand(left: int, right: int) -> tuple[int, int]:
            while left >= 0 and right < len(s) and s[left] == s[right]:
                left -= 1
                right += 1
            return left + 1, right - left - 1

        for i in range(len(s)):
            # Odd length palindrome (center is i)
            l1, len1 = expand(i, i)
            if len1 > max_len:
                start, max_len = l1, len1

            # Even length palindrome (center is between i and i + 1)
            l2, len2 = expand(i, i + 1)
            if len2 > max_len:
                start, max_len = l2, len2

        return s[start:start + max_len]
  • 패턴: Two Pointers, Dynamic Programming
  • 설명: 가장 긴 팰린드롬 부분문자열을 양쪽으로 확장하며 중심을 기준으로 탐색하는 방식으로, 좌우 포인터를 이용해 가능 구간을 확장시키는 패턴과 연결됩니다. 이 알고리즘은 확장을 반복하며 최댓값을 갱신하는 구조로 동작합니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n^2)
Space 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.

🏷️ 알고리즘 패턴 분석

rotate-image/dolphinflow86.py
# N is the number of rows and columns in the matrix.
# TC: O(N^2) - reversing rows takes O(N^2) and transposing across diagonal takes O(N^2)
# SC: O(1) - in-place rotation with no extra memory allocation

from typing import List


class Solution:

    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        # 1. Flip vertically (reverse rows)
        matrix.reverse()

        # 2. Transpose across main diagonal
        n = len(matrix)
        for i in range(n):
            for j in range(i + 1, n):
                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
  • 패턴: Two Pointers, Greedy, Dynamic Programming, Binary Search, Monotonic Stack, Hash Map / Hash Set, Backtracking, DFS, BFS, Divide and Conquer, Union Find, Trie, Bit Manipulation, Heap / Priority Queue, Sliding Window, Fast & Slow Pointers, Dynam ic Programming
  • 설명: 코드는 2차원 매트릭스 회전을 in-place로 수행하며, 먼저 행 반전(역순), 이후 대각선 반전(전치)을 수행한다. 이를 통해 공간 절약적 회전 알고리즘이 구현되며, 패턴은 주로 배열/매트릭스의 제어 흐름이 핵심이다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n^2)
Space O(1)

피드백: 두 단계 모두 전체 행렬의 모든 원소를 한 번씩 다루므로 시간은 O(n^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.

🏷️ 알고리즘 패턴 분석

subtree-of-another-tree/dolphinflow86.py
# M and N are the number of nodes in root and subRoot trees respectively.
# TC: O(M * N) - in the worst case, is_same is checked for every node in root
# SC: O(H) - recursion stack memory bounded by the height of root tree (up to O(M))

from typing import Optional


# 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 isSubtree(self, root: Optional["TreeNode"], subRoot: Optional["TreeNode"]) -> bool:
        if not subRoot:
            return True
        if not root:
            return False

        def is_same(s: Optional["TreeNode"], t: Optional["TreeNode"]) -> bool:
            if not s and not t:
                return True
            if not s or not t or s.val != t.val:
                return False
            return is_same(s.left, t.left) and is_same(s.right, t.right)

        if is_same(root, subRoot):
            return True

        return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)
  • 패턴: Depth-First Search, Backtracking
  • 설명: 루트 트리의 각 노드에서 서브트리와의 일치를 재귀적으로 검사하며, 서브트리 확인은 두 트리의 구조를 DFS로 비교합니다. 전체적으로 트리를 순차적으로 탐색하고 조건에 맞는 경우를 탐색하는 패턴이 보입니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n*m)
Space O(h)

피드백: 브루트의 모든 노드에 대해 서브트리 비교를 수행하므로 최악의 경우 O(n*m) 시간, 재귀 깊이는 트리의 높이에 비례하는 공간을 사용합니다.

개선 제안: 검색 최적화를 위해 문자열화 비교나 해시를 활용한 방법으로 개선 가능.

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

@dalestudy

dalestudy Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

📊 dolphinflow86 님의 학습 현황

이번 주 제출 문제

문제 난이도 유형 분석
alien-dictionary Hard ✅ 의도한 유형
construct-binary-tree-from-preorder-and-inorder-traversal Medium ✅ 의도한 유형
longest-palindromic-substring Medium ✅ 의도한 유형
rotate-image Medium ✅ 의도한 유형
subtree-of-another-tree Easy ✅ 의도한 유형

누적 학습 요약

  • 풀이한 문제: 71 / 75개
  • 이번 주 유형 일치율: 100% (5문제 중 5문제 일치)

문제 풀이 현황

카테고리 진행도 완료
Array ■■■■■■■ 10 / 10 (Medium 7, Easy 3)
Binary ■■■■■■■ 5 / 5 (Easy 4, Medium 1)
Dynamic Programming ■■■■■■■ 11 / 11 (Easy 1, Medium 10)
Graph ■■■■■■■ 8 / 8 (Hard 1, Medium 7)
Interval ■■■■■■■ 5 / 5 (Medium 4, Easy 1)
Linked List ■■■■■■■ 6 / 6 (Easy 3, Hard 1, Medium 2)
Heap ■■■■■■■ 3 / 3 (Hard 2, Medium 1)
String ■■■■■■□ 9 / 10 (Medium 5, Hard 1, Easy 3)
Tree ■■■■■■□ 12 / 14 (Medium 6, Hard 3, Easy 3)
Matrix ■■■■■□□ 3 / 4 (Medium 3)

🤖 이 댓글은 GitHub App을 통해 자동으로 작성되었습니다.

🔢 API 사용량 (gpt-5-nano)
요청 입력 토큰 출력 토큰 합계 비용
1 1,357 117 1,474 $0.000115
2 2,449 233 2,682 $0.000216
합계 3,806 350 4,156 $0.000330

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.

🏷️ 알고리즘 패턴 분석

alien-dictionary/dolphinflow86.py
# C is total length of all words, U is number of unique alien letters (<= 26).
# TC: O(C) - comparing adjacent words and processing topological sort graph
# SC: O(1) - unique letters and adjacency list bounded by 26 characters

from collections import deque
from typing import List


class Solution:

    def alienOrder(self, words: List[str]) -> str:
        adj = {char: set() for word in words for char in word}
        indegree = {char: 0 for word in words for char in word}

        for i in range(len(words) - 1):
            w1, w2 = words[i], words[i + 1]
            min_len = min(len(w1), len(w2))

            if len(w1) > len(w2) and w1[:min_len] == w2[:min_len]:
                return ""

            for j in range(min_len):
                if w1[j] != w2[j]:
                    if w2[j] not in adj[w1[j]]:
                        adj[w1[j]].add(w2[j])
                        indegree[w2[j]] += 1
                    break

        queue = deque([char for char in indegree if indegree[char] == 0])
        result = []

        while queue:
            char = queue.popleft()
            result.append(char)

            for neighbor in adj[char]:
                indegree[neighbor] -= 1
                if indegree[neighbor] == 0:
                    queue.append(neighbor)

        if len(result) < len(indegree):
            return ""

        return "".join(result)

    alien_order = alienOrder
  • 패턴: BFS, Dynamic Programming, Topological Sort
  • 설명: 알고리즘은 문자 간 선후관계를 그래프로 만들고 위상 정렬(BFS 기반)을 통해 순서를 도출하는 패턴입니다. 사이클 여부를 확인하며 부분 순서를 얻는 구조로, 그래프 탐색과 위상 정렬의 결합으로 문제를 풉니다.

📊 시간/공간 복잡도 분석

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

풀이 1: Solution.alienOrder — Time: O(C) / Space: O(U + E)
복잡도
Time O(C)
Space O(U + E)

피드백: 모든 문자에 대해 간선과 진입차수를 계산하고, 위상정렬로 결과를 얻는다. 유효하지 않은 경우 빈 문자열을 반환한다.

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

풀이 2: Solution.buildTree — Time: O(N) / Space: O(N)
복잡도
Time O(N)
Space O(N)

피드백: 사전 순회 인덱스를 전역처럼 다루며 inorder 맵을 이용해 루트 위치를 빠르게 찾는다.

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

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

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/dolphinflow86.py
# N is the number of nodes in the binary tree.
# TC: O(N) - building hashmap takes O(N), and each node is visited once in O(1) time
# SC: O(N) - hashmap takes O(N) space, and recursion call stack takes O(H) up to O(N)

from typing import List, Optional


# 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]) -> Optional[TreeNode]:
        inorder_map = {val: idx for idx, val in enumerate(inorder)}
        preorder_idx = 0

        def build(left: int, right: int) -> Optional[TreeNode]:
            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
  • 설명: 전위순회와 중위순회를 이용해 트리 재구성하는 문제로, 부분 트리 구간(left..right)을 분할해 재귀적으로 트리를 구성하는 방식이며, 중위순회 인덱스 매핑을 통해 빠르게 중위 구간 분할 위치를 찾는 해시 맵 패턴이 핵심입니다.

@parkhojeong parkhojeong left a comment

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.

마지막 주까지 수고 많으셨습니다!

@parkhojeong
parkhojeong merged commit 6129af2 into DaleStudy:main Oct 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Completed

Development

Successfully merging this pull request may close these issues.

2 participants