Skip to content

[daehyun99] WEEK 08 Solutions - #2816

Merged
parkhojeong merged 5 commits into
DaleStudy:mainfrom
daehyun99:W8
Aug 19, 2026
Merged

[daehyun99] WEEK 08 Solutions#2816
parkhojeong merged 5 commits into
DaleStudy:mainfrom
daehyun99:W8

Conversation

@daehyun99

@daehyun99 daehyun99 commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

답안 제출 문제

작성자 체크 리스트

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

검토자 체크 리스트

Important

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

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

Comment thread clone-graph/daehyun99.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/daehyun99.py
# Time: O(n)
# Space: 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']:
        have_to_look = set()
        seen = set()
        copied = {}

        have_to_look.add(node)

        while len(have_to_look) > 0 :
            curr = have_to_look.pop()
            if curr is not None:
                if curr.val not in copied:
                    copied[curr.val] = Node(curr.val, None)
                for neighbor in curr.neighbors:
                    if neighbor.val not in copied:
                        copied[neighbor.val] = Node(neighbor.val, None)
                        if neighbor.val not in seen:
                            have_to_look.add(neighbor)
                    copied[curr.val].neighbors.append(copied[neighbor.val])
                seen.add(curr.val)

        return copied.get(1, None)
  • 패턴: Hash Map / Hash Set, Breadth-First Search, Graph
  • 설명: 해당 코드는 그래프 순회를 위해 큐 대신 집합으로 너비를 관리하며, 노드 간 연결 정보 복제(깊은 복제)를 위해 해시 맵/세트를 사용합니다. 그래프의 각 노드를 방문하며 인접 노드를 큐처럼 확장하는 BFS 스타일 로직으로 그래프 복제를 수행합니다.

📊 시간/공간 복잡도 분석

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

풀이 1: Solution.cloneGraph — Time: O(N + E) / Space: O(N)
복잡도
Time O(N + E)
Space O(N)

피드백: 노드 고유 식별자로 val 을 사용해 복제, 해시맵으로 매핑하지만 노드 객체가 중복될 수 있어 실제 구현에서 id 기반 매핑이 더 안전하다.

개선 제안: 고려해볼 만한 대안: 노드 객체 자체를 키로 매핑하고, 각 노드의 객체를 직접 참조하는 방식으로 구현하면 중복 문제를 피할 수 있다.

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

피드백: 현재 구현은 노드 값을 키로 사용해 복제 노드를 저장하지만, 그래프에 같은 값의 노드가 여러 개 있을 수 있는 경우 문제가 생길 수 있다.

개선 제안: 고려해볼 만한 대안: 노드 객체를 직접 키로 사용하고, 깊이/너비 우선 탐색으로 실제 Node 객체 간의 매핑을 유지하도록 재구현.

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

@dalestudy

dalestudy Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

📊 daehyun99 님의 학습 현황

이번 주 제출 문제

문제 난이도 유형 분석
clone-graph Medium ⚠️ 유형 불일치
longest-repeating-character-replacement Medium ✅ 의도한 유형
palindromic-substrings Medium ✅ 의도한 유형
reverse-bits Easy ✅ 의도한 유형

누적 학습 요약

  • 풀이한 문제: 34 / 75개
  • 이번 주 유형 일치율: 75% (4문제 중 3문제 일치)

문제 풀이 현황

카테고리 진행도 완료
Array ■■■■■■□ 8 / 10 (Medium 5, Easy 3)
Matrix ■■■■■□□ 3 / 4 (Medium 3)
Dynamic Programming ■■■■□□□ 7 / 11 (Easy 1, Medium 6)
String ■■■■□□□ 6 / 10 (Medium 3, Easy 3)
Linked List ■■□□□□□ 2 / 6 (Easy 2)
Heap ■■□□□□□ 1 / 3 (Medium 1)
Tree ■■□□□□□ 4 / 14 (Medium 3, Easy 1)
Graph ■■□□□□□ 2 / 8 (Medium 2)
Binary ■□□□□□□ 1 / 5 (Easy 1)
Interval □□□□□□□ 0 / 5 ← 아직 시작 안 함

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

🔢 API 사용량 (gpt-5-nano)
요청 입력 토큰 출력 토큰 합계 비용
1 1,735 203 1,938 $0.000168
2 1,738 234 1,972 $0.000181
3 1,739 175 1,914 $0.000157
합계 5,212 612 5,824 $0.000505

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/daehyun99.py
# Time: O(s)
# Space: O(s)
from collections import defaultdict
class Solution:
    def characterReplacement(self, s: str, k: int) -> int:
        count = defaultdict(int)

        l = 0
        maxf = 0
        res = 0
        for r in range(len(s)):
            count[s[r]] += 1
            maxf = max(maxf, count[s[r]])

            while (r - l + 1) - maxf > k:
                count[s[l]] -= 1
                l += 1
            res = max(res, r - l + 1)
        return res

"""
# Time: O(s)
# Space: O(s)
class Solution:
    def characterReplacement(self, s: str, k: int) -> int:
        # find_bunch()
        bunch = []
        start_idx = 0
        start_word = s[0]
        for i in range(1, len(s)):
            if s[i] != start_word:
                bunch.append([start_word, i- start_idx])
                start_word = s[i]
                start_idx = i
        bunch.append([start_word, len(s) - start_idx])

        # find_LRCR()
        unique = set([c for c in s])
        result = 0

        for base in unique:
            changed_num = 0
            left = 0
            right = 0
            length = 0
            while right < len(bunch):
                if bunch[right][0] != base:
                    changed_num += bunch[right][1]
                length += bunch[right][1]
                right += 1

                while changed_num > k:
                    if bunch[left][0] != base:
                        changed_num -= bunch[left][1]
                    length -= bunch[left][1]
                    left += 1
                result = max(result, min(length + k - changed_num, len(s)))
        return result
"""
  • 패턴: Sliding Window, Greedy
  • 설명: 코드는 좌우 포인터를 이용해 부분 문자열의 길이를 확장/축소시키는 sliding window 기법과, 최댓값 유지 및 조건 만족 시 최적해를 갱신하는 Greedy 특성을 보입니다. 또한 반복 문자 최대 개수 제약을 통해 필요한 변환 수를 최소화하는 방식이라서 두 패턴이 함께 적용됩니다.

📊 시간/공간 복잡도 분석

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

🏷️ 알고리즘 패턴 분석

palindromic-substrings/daehyun99.py
class Solution:
    def countSubstrings(self, s: str) -> int:
        result = 0

        # odd
        for i in range(0, len(s)):
            m, n = i, i
            while 0 <= m and n < len(s) and s[m] == s[n]:
                result += 1
                m -= 1
                n += 1

        # even
        for i in range(0, len(s)-1):
            m, n = i, i+1
            while 0 <= m and n < len(s) and s[m] == s[n]:
                result += 1
                m -= 1
                n += 1
        return result


  • 패턴: Two Pointers, Monotonic Stack, Dynamic Programming
  • 설명: 주어진 코드는 문자열의 부분문자열 팰린드롬을 중앙에서 확장하는 방식으로 모든 팰린드롬을 탐색합니다. 이를 통해 길이에 따라 좌우 포인터를 확장하는 Two Pointers 패턴에 해당하며, 팰린드롬 여부를 +=로 누적하므로 간단한 DP 없이도 해결됩니다.

📊 시간/공간 복잡도 분석

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

피드백: 공간은 상수이며 시간은 모든 중심에서 확장하는 방식으로 계산한다.

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

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

Comment thread reverse-bits/daehyun99.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/daehyun99.py
class Solution:
    def reverseBits(self, n: int) -> int:
        res = 0
        for i in range(32):
            bit = (n >> i) & 1
            res += (bit << (31 - i))
        return res
  • 패턴: Bit Manipulation, Divide and Conquer
  • 설명: 주어진 코드는 비트를 앞으로 이동시켜 역순으로 뒤집는 연산으로 비트 조작을 직접 수행한다. 반복적으로 비트를 추출하고 위치를 바꿔 누적하는 방식은 비트 조작 패턴과 특정 구간 간 분할·합치의 아이디어를 활용하는 divide-and-conquer 형태로 볼 수 있다.

📊 시간/공간 복잡도 분석

복잡도
Time O(32)
Space O(1)

피드백: 정수의 각 비트를 순차적으로 뒤집어 최종 값을 구성한다.

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

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

@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.

수고하셨습니다. 복잡도 표기만 수정해주시면 될 거 같습니다!

Comment thread clone-graph/daehyun99.py Outdated
@@ -0,0 +1,33 @@
# Time: O(n)

@parkhojeong parkhojeong Aug 15, 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.

시간 복잡도에 노드 뿐 아니라 간선도 포함되어야 할 거 같습니다.

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.

그렇군요! O(N + E)네요

@@ -0,0 +1,59 @@
# Time: O(s)
# Space: O(s)

@parkhojeong parkhojeong Aug 15, 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.

공간 복잡도 표기가 잘못 되어 있네요.

@dalestudy dalestudy Bot 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.

현재 주차가 종료되어 자동으로 승인되었습니다. PR을 병합해주세요!

@parkhojeong

Copy link
Copy Markdown
Contributor

@daehyun99 커멘트 드린 부분 반영하신 후에 리뷰 요청 부탁드립니다.

Comment thread clone-graph/daehyun99.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/daehyun99.py
# Time: O(N + E
# Space: 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']:
        have_to_look = set()
        seen = set()
        copied = {}

        have_to_look.add(node)

        while len(have_to_look) > 0 :
            curr = have_to_look.pop()
            if curr is not None:
                if curr.val not in copied:
                    copied[curr.val] = Node(curr.val, None)
                for neighbor in curr.neighbors:
                    if neighbor.val not in copied:
                        copied[neighbor.val] = Node(neighbor.val, None)
                        if neighbor.val not in seen:
                            have_to_look.add(neighbor)
                    copied[curr.val].neighbors.append(copied[neighbor.val])
                seen.add(curr.val)

        return copied.get(1, None)
  • 패턴: Hash Map / Hash Set, Breadth-First Search
  • 설명: 그래프의 노드를 순차 방문하며 각 노드와 이웃을 복사해 새로운 그래프를 구성한다. 해시 맵으로 원래-복제 노드 매핑을 관리하고, 큐/집합으로 그래프를 탐색하는 BFS 형태의 순회가 보인다.

📊 시간/공간 복잡도 분석

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

피드백: 정확한 복제 노드 생성을 위한 맵과 방문 추적에 의한 탐색이다. 각 정점과 간선은 한 번씩 처리되므로 시간 복잡도는 선형이다.

개선 제안: 현재 구현은 노드 값으로 중복 여부를 판단하고 있어, 동일한 값의 서로 다른 노드가 있을 경우 의도하지 않은 동작을 유발할 수 있습니다. 노드 고유 식별자(노드 객체)를 키로 사용하는 맵으로 수정하면 안정성이 좋아집니다.

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

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/daehyun99.py
# Time: O(s)
# Space: O(1)from collections import defaultdict
class Solution:
    def characterReplacement(self, s: str, k: int) -> int:
        count = defaultdict(int)

        l = 0
        maxf = 0
        res = 0
        for r in range(len(s)):
            count[s[r]] += 1
            maxf = max(maxf, count[s[r]])

            while (r - l + 1) - maxf > k:
                count[s[l]] -= 1
                l += 1
            res = max(res, r - l + 1)
        return res

"""
# Time: O(s)
# Space: O(s)
class Solution:
    def characterReplacement(self, s: str, k: int) -> int:
        # find_bunch()
        bunch = []
        start_idx = 0
        start_word = s[0]
        for i in range(1, len(s)):
            if s[i] != start_word:
                bunch.append([start_word, i- start_idx])
                start_word = s[i]
                start_idx = i
        bunch.append([start_word, len(s) - start_idx])

        # find_LRCR()
        unique = set([c for c in s])
        result = 0

        for base in unique:
            changed_num = 0
            left = 0
            right = 0
            length = 0
            while right < len(bunch):
                if bunch[right][0] != base:
                    changed_num += bunch[right][1]
                length += bunch[right][1]
                right += 1

                while changed_num > k:
                    if bunch[left][0] != base:
                        changed_num -= bunch[left][1]
                    length -= bunch[left][1]
                    left += 1
                result = max(result, min(length + k - changed_num, len(s)))
        return result
"""
  • 패턴: Sliding Window, Greedy, Hash Map / Hash Set
  • 설명: 첫 코드 부분은 슬라이딩 윈도우로 부분 문자열의 길이를 확장하며 조건을 만족하는 최대 길이를 찾고, 카운트를 관리한다. 두 번째 구현은 구간들을 묶은 형태로 동작 로직에서 부분 문자열의 최적 길이를 탐색하는 방식으로 그리디 성격이 보이며, 부분 문자 집합과 윈도우 크기 조정에 해시/집합을 활용한다.

📊 시간/공간 복잡도 분석

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

풀이 1: Solution.characterReplacement — Time: ❌ O(s) → O(n) / Space: ✅ O(1) → O(1)
유저 분석 실제 분석 결과
Time O(s) O(n)
Space O(1) O(1)

피드백: 한 종류의 문자로 맞출 수 있는 최대 길이를 유지하기 위해 창의 최대 등장 횟수를 추적한다. 불필요한 중간 데이터는 제거되어 있다.

개선 제안: 제공된 두 번째 구현은 복잡도가 증가하며 불필요한 배열 조작이 많아 보입니다. 첫 번째 구현처럼 간단한 슬라이딩 윈도우 기법으로 통일하는 것이 좋습니다.

풀이 2: Solution.characterReplacement — Time: ❌ O(s) → O(n) / Space: ❌ O(s) → O(1)
유저 분석 실제 분석 결과
Time O(s) O(n)
Space O(s) 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-repeating-character-replacement/daehyun99.py
# Time: O(n)
# Space: O(1)
from collections import defaultdict
class Solution:
    def characterReplacement(self, s: str, k: int) -> int:
        count = defaultdict(int)

        l = 0
        maxf = 0
        res = 0
        for r in range(len(s)):
            count[s[r]] += 1
            maxf = max(maxf, count[s[r]])

            while (r - l + 1) - maxf > k:
                count[s[l]] -= 1
                l += 1
            res = max(res, r - l + 1)
        return res

"""
# Time: O(n)
# Space: O(1)
class Solution:
    def characterReplacement(self, s: str, k: int) -> int:
        # find_bunch()
        bunch = []
        start_idx = 0
        start_word = s[0]
        for i in range(1, len(s)):
            if s[i] != start_word:
                bunch.append([start_word, i- start_idx])
                start_word = s[i]
                start_idx = i
        bunch.append([start_word, len(s) - start_idx])

        # find_LRCR()
        unique = set([c for c in s])
        result = 0

        for base in unique:
            changed_num = 0
            left = 0
            right = 0
            length = 0
            while right < len(bunch):
                if bunch[right][0] != base:
                    changed_num += bunch[right][1]
                length += bunch[right][1]
                right += 1

                while changed_num > k:
                    if bunch[left][0] != base:
                        changed_num -= bunch[left][1]
                    length -= bunch[left][1]
                    left += 1
                result = max(result, min(length + k - changed_num, len(s)))
        return result
"""
  • 패턴: Sliding Window, Greedy, Hash Map / Hash Set
  • 설명: 주 코드 1은 슬라이딩 윈도우로 부분 문자열의 길이를 확장/수축하며 최대 대체 수를 추적한다. 또한 각 문자 등장 횟수를 세는 해시 맵을 사용하고, 조건 만족 시 윈도우를 이동하는 점에서 Greedy 성격이 보인다. 해시 맵을 활용해 문자 빈도 추적이 핵심이다.

📊 시간/공간 복잡도 분석

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

피드백: 한 번의 패스에서 현재 윈도우의 최대 등장 문자 수를 추적하여 조건을 검사한다. 해시맵을 이용해 문자 빈도수를 관리한다.

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

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

@daehyun99

Copy link
Copy Markdown
Contributor Author

@daehyun99 커멘트 드린 부분 반영하신 후에 리뷰 요청 부탁드립니다.

업데이트했습니다. 확인 부탁드려요!

@daehyun99
daehyun99 requested a review from parkhojeong August 19, 2026 07:30
@parkhojeong
parkhojeong merged commit 5a881a5 into DaleStudy:main Aug 19, 2026
1 check passed
@github-project-automation github-project-automation Bot moved this from In Review to Completed in 리트코드 스터디 8기 Aug 19, 2026
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