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
21 changes: 21 additions & 0 deletions 3sum/dolphinflow86.py

@alphaorderly alphaorderly Jul 1, 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.

오 이러면 왼쪽 포인터를 하나 두고
오른쪽 부분만 부분문제처럼 Two sum 문제로 푸신거리고 보면 될까요?
이런 방법도 있다니 너무 신기하네요! 고생하셨습니다!

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.

@alphaorderly 리뷰해주셔서 감사합니다. 네 해당 방식이 맞아요.
하지만 구현해놓고 보니 투포인터 방식이 좀 더 깔끔한 것 같긴 하더라구요 :)

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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Two Pointers, Hash Map / Hash Set, Greedy, Sorting
  • 설명: 코드는 정렬 후 하나의 원소를 고정하고 나머지 두 수를 합으로 찾는 방식으로 탐색한다. 내부에서 Hash Map으로 이전 값 여부를 확인해 중복 조합 제거를 수행한다.

📊 시간/공간 복잡도 분석

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

피드백: 정렬 후 중복 제거를 위해 i 인덱스의 이전 값과 비교하고, 내부에서 해시맵으로 보조 탐색을 수행합니다.

개선 제안: 현재 구현이 충분히 효율적이지만, 중복 제거를 더 엄격하게 관리하거나 두 포인터로 구현하면 상수 계수 개선이 가능합니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 1) Fix one element first, and then treat others as two-sum problem. Use set to get rid of duplicate combination.
# TC: O(N^2) where N is the length of nums.
# SC: O(N) where N is the length of nums.
class Solution:
def threeSum(self, nums: list[int]) -> list[list[int]]:
answer: Set[tuple[int,int,int]] = set()
n = len(nums)
nums.sort()

for i in range(n-2):
if i > 0 and nums[i] == nums[i-1]: continue

target = -nums[i]
nums_map: Dict[int, int] = {}
for j in range(i + 1, n):
comp = target - nums[j]
if comp in nums_map:
answer.add((nums[i], comp, nums[j]))
nums_map[nums[j]] = j

return [list(triplet) for triplet in answer]
20 changes: 20 additions & 0 deletions climbing-stairs/dolphinflow86.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Dynamic Programming, Memoization, Divide and Conquer
  • 설명: 재귀와 메모이제이션으로 중복 부분 문제를 해결하는 DP 성격의 풀이입니다. 비슷한 상태를 재사용해 트리 구조의 분할을 줄이고, 최종적으로 피보나치와 유사한 점화식으로 해결합니다.

📊 시간/공간 복잡도 분석

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

피드백: 상향식 동적 프로그래밍을 재귀로 구현해 중복을 제거했습니다. 메모이제이션으로 불필요한 재호출 감소.

개선 제안: 루틴을 반복문으로 변환하면 호출 스택 사용을 피하고 상수 공간으로 개선할 수 있습니다.

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# 1) Recursion with memoization.
# TC: O(N) where N is the given natural number.
# SC: O(N) where N is the given natural number.
class Solution:

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.

@JeonJe 이 문제는 각 스탭마다 행할 수 있는 행동이 1칸 아니면 2칸의 점프라고 생각했고 피보나치나 house robber 문제에서 풀었던 풀이를 적용해볼 수 있겠다라는 생각이 들어서 재귀로 접근했습니다. 실행 흐름은 1층부터 n층까지 재귀적으로 올라가되, n층에서 베이스케이스에 걸려 내려오면서 memo를 채우는식으로 구현하였고, 저도 헷갈려서 결정트리 그려보면서 다시 리마인드 했네요 :)

def climb_rec(self, n: int, step: int, memo: Dict[int, int]):
if step > n: return 0
if step in memo: return memo[step]
if step == n: return 1

first_way = self.climb_rec(n, step + 1, memo)
second_way = self.climb_rec(n, step + 2, memo)
memo[step] = first_way + second_way
return memo[step]


def climbStairs(self, n: int) -> int:
if n == 1: return 1

memo = {}
return self.climb_rec(n, 1, memo) + self.climb_rec(n, 2, memo)
20 changes: 20 additions & 0 deletions product-of-array-except-self/dolphinflow86.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# 1) Without using division operator and need to meet linear time complexity,
# calculate left accumulated product and calculate right accumulated product except iself and then
# product of left and right to get the result.
# TC: O(N) where N is the length of nums
# SC: O(N) where N is the length of nums
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
answer = [1] * n
acc = 1
for i in range(1, n):
acc *= nums[i-1]
answer[i] = acc

acc = 1
for i in range(n-2, -1, -1):
acc *= nums[i+1]
answer[i] *= acc

return answer
25 changes: 25 additions & 0 deletions valid-anagram/dolphinflow86.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 1) Sort input strings and check if those are the same.
# TC: O(NlogN) where N is the size of string s and t due to sorting
# SC: O(N) where N is the length of string s and t to store sorted list.
class Solution:

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.

안녕하세요! 이번에 코드리뷰를 맡게 된 이전제입니다. 잘부탁드립니다.

solve 코드 너무 깔끔하게 잘 작성하셨네요!!

시간복잡도를 더 낮춰야한다는 제약조건이 있다면, 정렬이 아닌 어떤 다른 방식으로 문제 풀이 접근하실 지 궁금합니다!

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.

@JeonJe 안녕하세요 전제님 :) 저도 잘 부탁드립니다.

이 문제는 시간복잡도를 더 낮춘다면 아래의 2번째 방법으로 푼 해시맵 사용하는 방법으로 접근하여 풀 것 같습니다.

다만 2번 솔루션에서도 s와 t가 영문 소문자 제한이 있어서 해시맵 대신에 26크기의 고정배열로 변경해서 푸는 것으로 조금

더 최적화를 할 수 있을 것 같아요.

def isAnagram(self, s: str, t: str) -> bool:
return sorted(s) == sorted(t)

# 2) Using dict to store count of the first string and decrease back to see if there's negative count.
# TC: O(N + M) where N is the length of s and M is the length of t.
# SC: O(N + M) where N is the length of s and M is the length of t.
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
if len(s) != len(t): return False

char_map: Dict[str, int] = {}
for ch in s:
char_map[ch] = char_map.get(ch, 0) + 1

for ch in t:
if ch not in char_map or char_map[ch] == 0:
return False

char_map[ch] -= 1

return True
22 changes: 22 additions & 0 deletions validate-binary-search-tree/dolphinflow86.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 1) Validate the BST using min and max values for each node.
# TC: O(N) where N is the number of nodes in the BST
# SC: O(H) where H is the height of the BST

# 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 solve(self, node: Optional[TreeNode], min: int, max: int) -> bool:
if node == None: return True

if node.val <= min or node.val >= max: return False

left = self.solve(node.left, min, node.val)
right = self.solve(node.right, node.val, max)
return left and right

def isValidBST(self, root: Optional[TreeNode]) -> bool:
return self.solve(root, float('-inf'), float('inf'))
Loading