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
54 changes: 54 additions & 0 deletions alien-dictionary/alphaorderly.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
class Solution:
def alienOrder(self, words: List[str]) -> str:
# 단어 개수 저장
N = len(words)

# 그래프와 진입차수 저장 구조 초기화
graph = defaultdict(list)
indegree = defaultdict(int)

# 단어 쌍을 차례로 비교하며 그래프와 진입차수 정보 구축
for i in range(1, N):
prev = words[i - 1]
curr = words[i]

# 예외: 앞 단어가 더 길고, 뒷 단어의 접두사라면 잘못된 사전 순서임
if len(prev) > len(curr) and prev.startswith(curr):
return ""

# 첫 번째로 다른 글자 쌍 찾아서 순서 규칙 추가
for prev_char, curr_char in zip(prev, curr):
if prev_char != curr_char:
if curr_char not in graph[prev_char]: # 중복 방지
graph[prev_char].append(curr_char)
indegree[curr_char] += 1
break # 한 쌍만 비교

# 등장하는 모든 글자 모음
characters = set("".join(words))

# 진입차수 0인 글자를 큐에 넣어 시작 노드로 설정
starts = deque([])
for char in characters:
if indegree[char] == 0:
starts.append(char)

ans = []

# 위상정렬(BFS) 진행
while starts:
node = starts.popleft()
ans.append(node)

# 현재 글자가 가리키는 다음 글자들의 진입차수 감소 및 0이 되면 큐에 추가
for dest in graph[node]:
indegree[dest] -= 1
if indegree[dest] == 0:
starts.append(dest)

# 모든 글자를 위상정렬 결과에 포함 못하면 순환이 존재 → 빈 문자열 반환
if len(ans) != len(characters):
return ""

# 위상정렬 결과를 문자열로 반환
return "".join(ans)
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
시간복잡도: O(n)
공간복잡도: O(n)

- inorder 배열의 값과 인덱스를 딕셔너리로 저장하여 검색을 빠르게 함
- preorder 배열을 순서대로 순회하며 각 노드의 값을 선택함 (루트부터 하위 트리 순)
- 선택된 값을 기준으로 inorder에서 왼쪽 구간(왼쪽 서브트리의 노드 개수), 오른쪽 구간을 계산
- preorder, inorder 구간의 인덱스를 재귀적으로 갱신하여 왼쪽, 오른쪽 서브트리를 구성
- 전체 트리를 재귀적으로 구성하며 그 결과를 반환
"""
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:

pos = {k: v for v, k in enumerate(inorder)}

def build(
pre: Tuple[int, int], ino: Tuple[int, int]
) -> Optional[TreeNode]:
if pre[0] > pre[1]:
return None

root = TreeNode(preorder[pre[0]])
center = pos[preorder[pre[0]]]

left_count = center - ino[0]

root.left = build(
(pre[0] + 1, pre[0] + left_count),
(ino[0], ino[0] + left_count - 1),
)
root.right = build(
(pre[0] + left_count + 1, pre[1]),
(ino[0] + left_count + 1, ino[1]),
)

return root

return build((0, len(preorder) - 1), (0, len(inorder) - 1))
28 changes: 28 additions & 0 deletions longest-palindromic-substring/alphaorderly.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
시간복잡도: O(n^2)
공간복잡도: O(1)

각 인덱스를 중심으로 팰린드롬을 확장하며 탐색
확장 함수로 팰린드롬의 좌우 경계 반환
가장 긴 팰린드롬 구간을 기록
"""
class Solution:
def longestPalindrome(self, s: str) -> str:
best_left = best_right = 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 - 1

for center in range(len(s)):
for left, right in (
expand(center, center),
expand(center, center + 1),
):
if right - left > best_right - best_left:
best_left, best_right = left, right

return s[best_left : best_right + 1]
18 changes: 18 additions & 0 deletions rotate-image/alphaorderly.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.

간결하게 나왔네요 !

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
시간복잡도: O(n^2)
공간복잡도: O(1)

- 행렬을 전치 행렬로 변환
- 각 행을 중간 열을 기준으로 뒤집음
"""
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
N = len(matrix)

for r in range(N):
for c in range(r + 1, N):
matrix[r][c], matrix[c][r] = matrix[c][r], matrix[r][c]

for r in range(N):
for c in range(N // 2):
matrix[r][c], matrix[r][-c - 1] = matrix[r][-c - 1], matrix[r][c]
37 changes: 37 additions & 0 deletions subtree-of-another-tree/alphaorderly.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.

이런 방법도 있군요

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
시간복잡도: O(n + m)
공간복잡도: O(n + m)

- subRoot 트리를 후위 순회하여 배열로 변환
- root의 각 노드마다 후위 순회 결과 배열을 구함
- 이 배열이 subRoot의 후위 순회 배열과 일치하는지 확인
- 같으면 True 반환, 아니면 계속 탐색
"""
class Solution:
def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
def postorder(node: TreeNode):
if not node:
return ["*"]

left = postorder(node.left)
right = postorder(node.right)
return left + right + [node.val]

sub_pos = postorder(subRoot)

def check(node: TreeNode):
if not node:
return (["*"], False)

left, left_valid = check(node.left)
right, right_valid = check(node.right)

if left_valid or right_valid:
return ([], True)

if left + right + [node.val] == sub_pos:
return ([], True)

return (left + right + [node.val], False)

return check(root)[1]
Loading