Skip to content

[daehyun99] WEEK 09 Solutions - #2831

Merged
parkhojeong merged 3 commits into
DaleStudy:mainfrom
daehyun99:W9
Aug 22, 2026
Merged

[daehyun99] WEEK 09 Solutions#2831
parkhojeong merged 3 commits into
DaleStudy:mainfrom
daehyun99:W9

Conversation

@daehyun99

@daehyun99 daehyun99 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

답안 제출 문제

작성자 체크 리스트

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

검토자 체크 리스트

Important

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

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

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.

🏷️ 알고리즘 패턴 분석

linked-list-cycle/daehyun99.py
# Time: O(N)
# Space: O(N)
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def hasCycle(self, head: Optional[ListNode]) -> bool:
        seen = set()

        curr = head

        while curr is not None:
            if curr.next in seen:
                return True
            seen.add(curr.next)
            curr = curr.next

        return False
  • 패턴: Hash Map / Hash Set, Two Pointers
  • 설명: head를 순회하면서 각 노드를 집합에 저장해 이미 본 노드인지 확인하는 해시 세트 기반 탐색 패턴이 사용됩니다. 반복문으로 순회하지만 실제 탐색은 해시 집합으로 중복 여부를 검사합니다.

📊 시간/공간 복잡도 분석

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

피드백: 해시셋에 노드를 저장해 순회 시 중복 방문 여부를 확인하는 방식으로 동작한다.

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

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

@dalestudy

dalestudy Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

📊 daehyun99 님의 학습 현황

이번 주 제출 문제

문제 난이도 유형 분석
linked-list-cycle Easy ⚠️ 유형 불일치
maximum-product-subarray Medium ⚠️ 유형 불일치
minimum-window-substring Hard ⚠️ 유형 불일치
pacific-atlantic-water-flow Medium ⚠️ 유형 불일치
sum-of-two-integers Medium ⚠️ 유형 불일치

누적 학습 요약

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

문제 풀이 현황

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

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

🔢 API 사용량 (gpt-5-nano)
요청 입력 토큰 출력 토큰 합계 비용
1 2,456 216 2,672 $0.000209

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.

🏷️ 알고리즘 패턴 분석

maximum-product-subarray/daehyun99.py
# Time: O(N)
# Space: O(N)
class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        zero_idx = set([i for i in range(len(nums)) if nums[i] == 0])
        prefix = [0 for _ in  range(len(nums))]
        suffix = [0 for _ in  range(len(nums))]

        val = 1
        for i in range(len(nums)):
            if i in zero_idx:
                val = 1
                continue
            else:
                val *= nums[i]
                prefix[i] = val
        val = 1
        for i in range(len(nums)-1, -1, -1):
            if i in zero_idx:
                val = 1
                continue
            else:
                val *= nums[i]
                suffix[i] = val
        return max(max(prefix), max(suffix))
  • 패턴: Prefix / Suffix Product (using prefix and suffix arrays)
  • 설명: 연속 구간의 곱을 0을 기준으로 나눠 왼쪽과 오른쪽에서 누적 곱을 계산하는 패턴으로, 두 포인터나 슬라이딩 윈도우 대신 prefix/suffix 누적으로 최대 곱을 구하는 기법입니다.

📊 시간/공간 복잡도 분석

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

피드백: 0을 구분자로 삼아 프리픽스와 서픽스를 계산하고 최댓값을 비교한다.

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

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.

🏷️ 알고리즘 패턴 분석

minimum-window-substring/daehyun99.py
from collections import Counter
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        check = Counter(t)

        for i, c in enumerate(s):
            if c in check:
                check[c] -= 1
        for key, val in check.items():
            if val > 0:
                return ""
        else:
            for i in range(len(s)):
                c = s[i]
                if c in check:
                    if check[c] == 0:
                        left = i
                        break
                    check[c] += 1
            right = len(s)-1
            result = s[left:right+1]

            while left < right and 0 <= left:
                if s[right] in check:
                    check[s[right]] += 1
                    if check[s[right]] <= 0:
                        if left < right and len(result) > right - left:
                            result = s[left:right]
                        right -= 1

                    else:
                        while check[s[right]] > 0:
                            left -= 1
                            if s[left] in check:
                                check[s[left]] -= 1
                        if left < right and len(result) > right - left:
                            result = s[left:right]
                        right -= 1
                else:
                    if len(result) > right - left:
                        result = s[left:right]
                    right -= 1
            return result
  • 패턴: Two Pointers, Sliding Window, Hash Map / Hash Set
  • 설명: 최소 윈도우 부분 문자열 탐색으로, 부분 문자열의 양쪽 포인터를 조정하면서 윈도우를 확장/축소하는 과정이 핵심이다. 해시 맵(Counter)으로 필요한 문자 개수를 추적하고, 슬라이딩 윈도우의 좌우 경계를 이동하며 조건을 만족하는 최솟값을 찾는다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n * k)
Space O(k)

피드백: Counter를 이용해 문자 빈도를 관리하지만 전체 알고리즘 흐름이 최적의 투 포인터 방식과 다소 다를 수 있다.

개선 제안: 현재 구현이 충분히 작동하나, 표준 슬라이딩 윈도우 방식으로 개선하면 시간 복잡도가 더 명확해진다.

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

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.

🏷️ 알고리즘 패턴 분석

pacific-atlantic-water-flow/daehyun99.py
# Time: O(m*n)
# Space: O(m*n)
class Solution:
    def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
        def check(matrix, matrix_seen):
            while len(matrix) > 0:
                m,n = matrix.pop()
                if m+1 < len(heights) and heights[m][n] <= heights[m+1][n] and (m+1,n) not in matrix_seen:
                    matrix.add((m+1,n))
                    matrix_seen.add((m+1,n))
                if m-1 >= 0 and heights[m][n] <= heights[m-1][n] and (m-1,n) not in matrix_seen:
                    matrix.add((m-1,n))
                    matrix_seen.add((m-1,n))
                if n+1 < len(heights[0]) and heights[m][n] <= heights[m][n+1] and (m,n+1) not in matrix_seen:
                    matrix.add((m,n+1))
                    matrix_seen.add((m,n+1))
                if n-1 >= 0 and heights[m][n] <= heights[m][n-1] and (m,n-1) not in matrix_seen:
                    matrix.add((m,n-1))
                    matrix_seen.add((m,n-1))
            return matrix_seen

        pacific = set()
        pacific_seen = set()
        for i in range(len(heights[0])):
            pacific.add((0, i))
            pacific_seen.add((0, i))
        for i in range(1, len(heights)):
            pacific.add((i, 0))
            pacific_seen.add((i, 0))
        
        p_seen = check(pacific, pacific_seen)

        atlantic = set()
        atlantic_seen = set()
        for i in range(len(heights[0])):
            atlantic.add((len(heights)-1, i))
            atlantic_seen.add((len(heights)-1, i))
        for i in range(0, len(heights)):
            atlantic.add((i, len(heights[0])-1))
            atlantic_seen.add((i, len(heights[0])-1))
    
        a_seen = check(atlantic, atlantic_seen)

        result = []
        for p in p_seen:
            if p in a_seen:
                result.append(list(p))
        return result
  • 패턴: BFS, Hash Map / Hash Set
  • 설명: 두 바다로부터 높이 조건을 만족하는 칸으로 확산시키며 도달 여부를 각각의 BFS로 확인하고, 교차 지점을 찾는 형태로 구현되어 있습니다. 좌표를 큐 대신 스택처럼 다루는 비트 다중 탐색의 구조를 통해 그래프 탐색 패턴이 드러납니다.

📊 시간/공간 복잡도 분석

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

피드백: 두 해수면의 경계에서 출발해 인접한 높이가 같거나 큰 방향으로 확장하는 구현이다.

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

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.

🏷️ 알고리즘 패턴 분석

sum-of-two-integers/daehyun99.py
# Time: O(1)
# Space: O(1)
class Solution:
    def getSum(self, a: int, b: int) -> int:
        mask = 0xFFFFFFFF
        max_int = 0x7FFFFFFF

        while b != 0 :
            carry = (a&b) << 1
            a = (a ^ b) & mask
            b = carry & mask

        return a if a <= max_int else ~(a ^ mask)

"""
# Time: O(N)
# Space: O(N)
class Solution:
    def getSum(self, a: int, b: int) -> int:
        pos = []
        neg = []

        for i in [a, b]:
            if i < 0 :
                for j in range(i, 0):
                    neg.append(0)
            else:
                for j in range(i):
                    pos.append(0)
        if len(neg) <= len(pos):
            for i in range(len(neg)):
                pos.pop()
            return len(pos)
        else:
            for i in range(len(pos)):
                neg.pop()
            return -1 * len(neg)
"""
  • 패턴: Bit Manipulation
  • 설명: 첫 번째 구현은 비트 연산과 마스킹을 이용해 덧셈의 자리올림을 처리하는 비트 조작 패턴으로 분류됩니다. 두 번째 부분은 비효율적 리스트 조작으로 보이나, 주된 구현은 비트 조작 패턴을 포함합니다.

📊 시간/공간 복잡도 분석

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

피드백: 첫 번째 구현은 비트 연산을 이용해 음수까지 처리하는 표준 방법이다.

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

@parkhojeong
parkhojeong self-requested a review August 22, 2026 12:59

@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 on lines +5 to +20
def check(matrix, matrix_seen):
while len(matrix) > 0:
m,n = matrix.pop()
if m+1 < len(heights) and heights[m][n] <= heights[m+1][n] and (m+1,n) not in matrix_seen:
matrix.add((m+1,n))
matrix_seen.add((m+1,n))
if m-1 >= 0 and heights[m][n] <= heights[m-1][n] and (m-1,n) not in matrix_seen:
matrix.add((m-1,n))
matrix_seen.add((m-1,n))
if n+1 < len(heights[0]) and heights[m][n] <= heights[m][n+1] and (m,n+1) not in matrix_seen:
matrix.add((m,n+1))
matrix_seen.add((m,n+1))
if n-1 >= 0 and heights[m][n] <= heights[m][n-1] and (m,n-1) not in matrix_seen:
matrix.add((m,n-1))
matrix_seen.add((m,n-1))
return matrix_seen

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.

음...
queue나 stack처럼 접근해서 풀었습니다. (matrix를 queue로 생각하시면 편하실 것 같습니다)

예를 들어, Pacific으로 무조건 흐르는 위치는 행이 0이거나, 열이 0이면 흐르는데요.
Pacific으로 흐르는 열들을 matrix에 넣고, 해당 위치의 값과 같거나 큰 주변의 좌표를 check() 함수에서 찾고, matrix에 추가하는 형태입니다.

마찬가지로, Atlantic에서도 동일한 과정을 진행 후, 교집합을 찾으면 두 바다로 모두 흐르는 위치만 남게 됩니다.

Image

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

바다 쪽에서 시작해서 찾는 방식이군요. 상세히 설명 해주셔서 쉽게 이해했습니다. 감사합니다.

Comment on lines +23 to +43
while left < right and 0 <= left:
if s[right] in check:
check[s[right]] += 1
if check[s[right]] <= 0:
if left < right and len(result) > right - left:
result = s[left:right]
right -= 1

else:
while check[s[right]] > 0:
left -= 1
if s[left] in check:
check[s[left]] -= 1
if left < right and len(result) > right - left:
result = s[left:right]
right -= 1
else:
if len(result) > right - left:
result = s[left:right]
right -= 1
return result

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.

혹시 어떤 방식으로 푸신건지 설명 부탁드려도 될까요?

@daehyun99 daehyun99 Aug 22, 2026

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.

먼저 check에다가 찾아야하는 각 문자열들의 갯수를 찾고요.

그 후, s에 들어있는 문자열들에 1씩 빼줍니다.(line 6 ~8)

그러면, check 안의 값이 무조건 음수이거나 0이여야 t의 조건을 다 만족하게 됩니다.

이 상황에서 line 13 ~ 19 코드로 t의 조건을 만족하는 s의 끝에서부터 시작하는 left 인덱스 좌표를 찾고, rightlen(s)-1가 됩니다.

그 다음에는 right를 왼쪽으로 옮겨가면서, t 조건을 만족하는지 확인합니다(check 안에 양수가 존재하는지),

예를 들어, 아래의 경우 s[right]C일 때, t에는 C가 들어가야해서, right에 -1를 더할 수가 없는데요.
이때, left를 옮겨가면서 s[left]C인 경우를 찾습니다.
만약 찾았다면, right를 -1할 수 있습니다.

그 후, 원래의 정답 문자열의 길이와 새로 찾은 s[left:right]의 길이를 비교 후, 길이가 짧은 문자열을 정답으로 반환하게 됩니다.

Image

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 7a27a90 into DaleStudy:main Aug 22, 2026
3 checks passed
@github-project-automation github-project-automation Bot moved this from In Review to Completed in 리트코드 스터디 8기 Aug 22, 2026
@daehyun99
daehyun99 deleted the W9 branch August 22, 2026 17:08
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