Skip to content
Open
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
20 changes: 20 additions & 0 deletions container-with-most-water/parkhojeong.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Two Pointers, Greedy
  • 설명: 왼쪽과 오른쪽 포인터를 두고 가능한 용적을 계산하며 더 큰 벽을 버리는 방식으로 최적 해를 찾는 패턴으로, 한 번의 선형 순회로 해결하는 그리디+투 포인터 접근입니다.

📊 시간/공간 복잡도 분석

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

풀이 1: Solution.maxArea — Time: O(n) / Space: O(1)
복잡도
Time O(n)
Space O(1)

피드백: 왼쪽/오른쪽 포인터를 한 칸씩 이동시키며 최대 넓이를 갱신합니다. 추가 공간 없이 상수 공간으로 구현되어 있습니다.

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

풀이 2: WordDictionary.addWord — Time: O(n) / Space: O(sum 길이)
복잡도
Time O(n)
Space O(sum 길이)

피드백: Trie를 사용해 단어를 저장하고 '.'를 모든 자식으로 확장하며 검색합니다. 구현에 여러 보조 메서드가 섞여 있어 유지보수 측면에서 다소 복잡합니다.

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

풀이 3: WordDictionary.search — Time: O(m) / Space: O(sum 길이)
복잡도
Time O(m)
Space O(sum 길이)

피드백: 재귀로 '.'를 모든 자식 노드에 대해 탐색합니다. 최악의 경우 지수적으로 증가할 수 있습니다.

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

풀이 4: Trie.addWord — Time: O(n) / Space: O(sum 길이)
복잡도
Time O(n)
Space O(sum 길이)

피드백: 연속된 문자로 트리를 구성하고 마지막 문자에 종료 플래그를 설정합니다.

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

풀이 5: Trie.__init__ — Time: O(1) / Space: O(1)
복잡도
Time O(1)
Space O(1)

피드백: 루트 노드를 하나 생성합니다.

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

풀이 6: Node.__init__ — Time: O(1) / Space: O(1)
복잡도
Time O(1)
Space O(1)

피드백: 노드의 문자 정보와 종료 여부, 자식 맵을 초기화합니다.

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

풀이 7: Node.getChild — Time: O(1) / Space: O(1)
복잡도
Time O(1)
Space O(1)

피드백: 해당 문자 존재 여부를 해시맵에서 즉시 조회합니다.

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

풀이 8: Node.getAllChild — Time: O(1) / Space: O(k)
복잡도
Time O(1)
Space O(k)

피드백: 자식 컬렉션의 뷰를 반환합니다.

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

풀이 9: Node.addChild — Time: O(1) / Space: O(1)
복잡도
Time O(1)
Space O(1)

피드백: 자식 맵에 노드를 삽입합니다.

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

풀이 10: WordDictionary — Time: O(1) / Space: O(sum 길이)
복잡도
Time O(1)
Space O(sum 길이)

피드백: Trie를 래핑해 addWord와 search를 제공합니다.

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

풀이 11: WordDictionary.__init__ — Time: O(1) / Space: O(1)
복잡도
Time O(1)
Space O(1)

피드백: 트라이를 내부에 구성합니다.

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class Solution:
def maxArea(self, height: List[int]) -> int:
i = 0
j = len(height) - 1
max_amount = 0

while i < j:
left_height = height[i]
right_height = height[j]

amount = min(left_height, right_height) * (j - i)
if amount > max_amount:
max_amount = amount

if left_height > right_height:
j -= 1
else:
i += 1

return max_amount
89 changes: 89 additions & 0 deletions design-add-and-search-words-data-structure/parkhojeong.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Trie, Backtracking, Dynamic Programming
  • 설명: 이 코드는 Trie(접두사 트리)를 이용해 단어를 저장하고 검색합니다. 검색에서 '.' 와일드카드를 재귀적으로 탐색하는 부분은 부분 문자열 매칭에 대한 백트래킹 성질을 보이며, 전체적으로 단어 탐색을 위한 트리 구조를 활용합니다.

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.

  1. getter와 setter를 사용하실 예정이시라면 Python에서는 각 property의 이름 앞에 _ 를 붙이는것이 관례라고 알고 있습니다.

self._is_end, self._child

  1. 해당 문제는 단일 클래스로 해결이 가능한 문제인데, 3개까지 나누는것은 아주 개인적으로는 좀 오버 엔지니어링이 아닐까 하는 생각이 들어요,

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

1의 예시입니다.
_query는 숨기는것에 해당하고 ( private 접근 제어자에 해당 )
query는 보여주는것에 해당합니다 ( public 접근 제어자에 해당 )

def _query(
        self,
        node_index: int,
        seg_left: int,
        seg_right: int,
        qur_left: int,
        qur_right: int,
    ) -> int:
        if seg_right < qur_left or qur_right < seg_left:
            return 0

        if qur_left <= seg_left <= seg_right <= qur_right:
            return self.tree[node_index]

        mid = (seg_left + seg_right) // 2
        left = self._query(node_index * 2, seg_left, mid, qur_left, qur_right)
        right = self._query(node_index * 2 + 1, mid + 1, seg_right, qur_left, qur_right)

        return max(left, right)

def query(self, left: int, right: int) -> int:
    if left > right:
        return 0
    return self._query(1, 0, self.n - 1, left, right)

Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
class Node:
ch = ""
is_end = False
child: List[Node] = None
child: dict[str, Node] = None
Comment on lines +2 to +5

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.

해당 부분은 클래스 변수를 선언하신것 같은데 삭제해도 무방할것 같아요!


def __init__(self, ch, is_end):
self.ch = ch
self.is_end = is_end
self.child = {}

def getIsEnd(self):
return self.is_end

def setIsEndTrue(self):
self.is_end = True

def getChild(self, ch) -> None:
if ch in self.child:
return self.child[ch]

return None

def getAllChild(self) -> List[Node]:
return self.child.values()

def addChild(self, node):
self.child[node.ch] = node

class Trie:
def __init__(self):
self.root = Node("", False)

def addWord(self, word) -> None:
i = 0
node = self.root
while i < len(word):
ch = word[i]
child_node = node.getChild(ch)
if child_node:
node = child_node
if i == len(word) - 1:
node.setIsEndTrue()
else:
is_end = True if i == len(word) - 1 else False
child_node = Node(ch, is_end)
node.addChild(child_node)
node = child_node

i += 1

def search(self, word: str, i, node) -> bool:
if word[i] == ".":
child_nodes = node.getAllChild()
else:
child_node = node.getChild(word[i])
if child_node is None:
return False
child_nodes = [child_node]

for child_node in child_nodes:
if i == len(word) - 1:
if child_node.getIsEnd() is True:
return True
else:
continue

if self.search(word, i + 1, child_node):
return True

return False


class WordDictionary:
def __init__(self):
self.trie = Trie()

def addWord(self, word: str) -> None:
self.trie.addWord(word)

def search(self, word: str) -> bool:

return self.trie.search(word, 0, self.trie.root)


# Your WordDictionary object will be instantiated and called as such:
# obj = WordDictionary()
# obj.addWord(word)
# param_2 = obj.search(word)
14 changes: 14 additions & 0 deletions longest-increasing-subsequence/parkhojeong.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
  • 설명: 숫자 배열의 부분수열 길이를 부분문제로 나누어 각 위치까지의 최장 증가 부분수열 길이를 저장하는 전형적인 DP(전형적 동적계획법) 패턴입니다.

📊 시간/공간 복잡도 분석

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

피드백: 각 i에 대해 앞선 j들을 확인하며 LIS 길이를 갱신하는 전형적인 DP 풀이입니다.

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

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

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.

N Log N 풀이도 꼭 한번 시도 해 보시죠!

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
dp = [0] * len(nums)
max_count = 0

for i in range(len(nums)):
dp[i] = 1
for j in range(i):
if nums[j] < nums[i]:
dp[i] = max(dp[j] + 1, dp[i])

max_count = max(max_count, dp[i])

return max_count
49 changes: 49 additions & 0 deletions spiral-matrix/parkhojeong.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Monotonic Stack, Hash Map / Hash Set, Greedy, Divide and Conquer, Two Pointers, Sliding Window, Fast & Slow Pointers, BFS, DFS, Backtracking, Dynamic Programming, Binary Search, Union Find, Trie, Bit Manipulation
  • 설명: 해당 코드는 나선형(스파이럴) 순회로 행렬을 순회하며 방문 표시를 통해 경로를 탐색합니다. 경로를 따라 좌우상하 방향으로 갯수를 확장하는 방식은 Sliding Window/Two Pointers와 유사한 순차적 확장 패턴에 가깝고, 방문 여부 확인은 상태 관리로 Hash Set/Hash Map의 개념과 연결될 수 있습니다. 그러나 핵심은 나선 방향으로 움직이며 모든 원소를 방문하는 탐색 로직으로, DFS/BFS의 단순 구현이라기보단 방향 전환과 경계 체크를 반복하는 탐색 패턴에 가깝습니다.

📊 시간/공간 복잡도 분석

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

피드백: 제자리 방문 표식과 경계 검사로 모든 원소를 한 번씩 방문합니다.

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
VISITED = '#'

class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
row = 0
col = 0

visit = []

def canGo(row, col):
if row < 0 or row >= len(matrix) or col < 0 or col >= len(matrix[0]):
return False

if matrix[row][col] == VISITED:
return False

return True

while True:
if not (canGo(row, col + 1) or canGo(row + 1, col) or canGo(row, col - 1) or canGo(row - 1, col)):
break

while canGo(row, col + 1):
visit.append(matrix[row][col])

matrix[row][col] = VISITED
col += 1

while canGo(row + 1, col):
visit.append(matrix[row][col])

matrix[row][col] = VISITED
row += 1

while canGo(row, col - 1):
visit.append(matrix[row][col])

matrix[row][col] = VISITED
col -= 1

while canGo(row - 1, col):
visit.append(matrix[row][col])

matrix[row][col] = VISITED
row -= 1

visit.append(matrix[row][col])

return visit
26 changes: 26 additions & 0 deletions valid-parentheses/parkhojeong.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.

🏷️ 알고리즘 패턴 분석

  • 패턴: Stack
  • 설명: 스택을 이용해 여는 괄호를 저장하고 닫는 괄호를 만날 때 스택의 탑과 매칭 여부를 확인하는 방식으로 올바른 괄호 문자열을 판별합니다. 순차 탐색과 스택 연산으로 구현된 대표적인 괄호 문제 풀이입니다.

📊 시간/공간 복잡도 분석

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

close_parenthesis_map 만들어두신 이거 자체가
'(' in close_parenthesis_map 과 같이 사용시 key값에 한해 키에 해당 값이 있는지 체크한다는게 있다는것을 아시나요?
그러면 set을 없애고도 동일한 코드를 그대로 구현할수 있습니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class Solution:
def isValid(self, s: str) -> bool:
stack = []

open_parenthesis_set = set({"{", "[", "("})
close_parenthesis_map = {
"]": "[",
")": "(",
"}": "{"
}

for ch in s:
if ch in open_parenthesis_set:
stack.append(ch)
else:
if len(stack) == 0:
return False

top = stack.pop()
if close_parenthesis_map[ch] != top:
return False

if len(stack) > 0:
return False

return True
Loading