visited 집합을 사용하여 중복 방문을 방지합니다.from collections import deque
from typing import List, Optional
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]:
if not root:
return []
# 부모 노드를 저장할 딕셔너리
parent = {}
# 부모 노드를 해싱하여 기록
def map_parents(node):
if node.left:
parent[node.left] = node
map_parents(node.left)
if node.right:
parent[node.right] = node
map_parents(node.right)
map_parents(root)
# BFS로 K 거리의 노드 탐색
q = deque([target])
visited = set([target])
distance = 0
while q:
if distance == k: # K 거리 도달 시 현재 큐에 있는 노드 값 반환
return [node.val for node in q]
for _ in range(len(q)):
node = q.popleft()
# 자식 노드와 부모 노드 순회
for neighbor in (node.left, node.right, parent.get(node)):
if neighbor and neighbor not in visited:
visited.add(neighbor)
q.append(neighbor)
distance += 1
return []
visited 집합: O(N)current_min).current_max).# 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
from typing import Optional
class Solution:
def maxAncestorDiff(self, root: Optional[TreeNode]) -> int:
def dfs(node):
nonlocal max_diff
if not node:
return float('inf'), float('-inf') # 초기값: 무한대로 설정 (최소값/최대값 계산)
# 좌측 및 우측 서브트리의 최소값, 최대값 계산
left_min, left_max = dfs(node.left)
right_min, right_max = dfs(node.right)
# 현재 노드 기준 최소값과 최대값 계산
current_min = min(node.val, left_min, right_min)
current_max = max(node.val, left_max, right_max)
# 최대 차이값 갱신
max_diff = max(
max_diff,
abs(node.val - current_min),
abs(node.val - current_max)
)
return current_min, current_max
max_diff = 0
dfs(root) # DFS 탐색 시작
return max_diff
visited 집합에 추가하여 중복 순회를 방지합니다.from collections import deque
from typing import List, Optional
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]:
if not root:
return []
# 부모 노드 저장
parent = {}
def map_parents(node):
if node.left:
parent[node.left] = node
map_parents(node.left)
if node.right:
parent[node.right] = node
map_parents(node.right)
map_parents(root)
# BFS 탐색
q = deque([target])
visited = set([target])
distance = 0
while q:
if distance == k:
return [node.val for node in q]
for _ in range(len(q)):
node = q.popleft()
for neighbor in (node.left, node.right, parent.get(node)):
if neighbor and neighbor not in visited:
visited.add(neighbor)
q.append(neighbor)
distance += 1
return []
visited 집합: O(N)from collections import deque
from typing import Optional
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def subtreeWithAllDeepest(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return None
# 부모 노드 저장
parent = {}
deepest_nodes = []
# BFS로 가장 깊은 노드 찾기
q = deque([root])
while q:
deepest_nodes = list(q)
for _ in range(len(q)):
node = q.popleft()
if node.left:
parent[node.left] = node
q.append(node.left)
if node.right:
parent[node.right] = node
q.append(node.right)
# 가장 깊은 노드들의 공통 부모 탐색
while len(deepest_nodes) > 1:
deepest_nodes = list(set(parent[node] for node in deepest_nodes))
return deepest_nodes[0]
from typing import List, Optional
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def constructFromPrePost(self, preorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
def build(preorder, postorder):
if not preorder or not postorder:
return None
root = TreeNode(preorder[0])
if len(preorder) == 1:
return root
# 왼쪽 서브트리 크기 계산
left_root_val = preorder[1]
left_subtree_size = postorder.index(left_root_val) + 1
# 왼쪽과 오른쪽 서브트리 재귀 생성
root.left = build(preorder[1:1 + left_subtree_size], postorder[:left_subtree_size])
root.right = build(preorder[1 + left_subtree_size:], postorder[left_subtree_size:-1])
return root
return build(preorder, postorder)
from collections import deque
class Solution:
def reverseOddLevels(self, root: TreeNode) -> TreeNode:
def reverse(nodes):
i, j = 0, len(nodes) - 1
while i < j:
nodes[i].val, nodes[j].val = nodes[j].val, nodes[i].val
i, j = i + 1, j - 1
q = deque([root])
level = 0
while q:
level_size = len(q)
nodes = []
for _ in range(level_size):
node = q.popleft()
if node.left:
q.append(node.left)
q.append(node.right)
nodes.append(node.left)
nodes.append(node.right)
if level % 2 == 1:
reverse(nodes)
level += 1
return root
class Solution:
def reverseOddLevels(self, root: TreeNode) -> TreeNode:
def dfs(left, right, level):
if not left or not right:
return
if level % 2 == 1:
left.val, right.val = right.val, left.val
dfs(left.left, right.right, level + 1)
dfs(left.right, right.left, level + 1)
dfs(root.left, root.right, 1)
return root
class Solution:
def mostProfitablePath(self, edges: List[List[int]], bob: int, amount: List[int]) -> int:
def dfs_bob(node, level):
visited[node] = True
if node == 0:
return True
for next_node in tree[node]:
if not visited[next_node]:
bob_path[next_node] = level + 1
if dfs_bob(next_node, level + 1):
return True
del bob_path[next_node]
return False
def dfs_alice(node,level,total):
nonlocal bob_path, ans
visited[node]=1
if node in bob_path:
if bob_path[node] == level:
total += amount[node]//2
elif bob_path[node] > level:
total += amount[node]
else:
total += amount[node]
is_leaf = True
for next_node in tree[node]:
if not visited[next_node]:
is_leaf = False
dfs_alice(next_node,level+1,total)
if is_leaf:
ans = max(ans,total)
tree = defaultdict(list)
for u,v in edges:
tree[u].append(v)
tree[v].append(u)
visited = [False] * len(amount)
bob_path = {bob: 0}
dfs_bob(bob, 0)
visited = [False] * len(amount)
ans = float('-inf')
dfs_alice(0,0,0)
return ans
O(N)
O(N)
# 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 minimumOperations(self, root: Optional[TreeNode]) -> int:
def sort(lst):
target = sorted(lst)
swap = 0
pos = {val: idx for idx,val in enumerate(lst)}
for i in range(len(lst)):
if lst[i]!=target[i]:
swap+=1
lst[pos[target[i]]] = lst[i]
pos[lst[i]] = pos[target[i]]
lst[i] = target[i]
pos[target[i]] = i
return swap
def bfs(root):
q = deque([root])
total = 0
while q:
cur_level = []
for _ in range(len(q)):
node = q.popleft()
cur_level.append(node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
total += sort(cur_level)
return total
return bfs(root)
O(N Log N)
O(N)
# 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 closestNodes(self, root: Optional[TreeNode], queries: List[int]) -> List[List[int]]:
def tree_to_array(root):
nonlocal tree
if not root:
return
tree_to_array(root.left)
tree.append(root.val)
tree_to_array(root.right)
tree = []
tree_to_array(root)
print(tree)
ans = []
for q in queries:
s=0
f=len(tree)-1
mid = (s+f)//2
flag = False
while s<=f:
mid = (s+f)//2
if tree[mid] == q:
ans.append([q,q])
flag = True
break
elif tree[mid] > q:
f = mid-1
else:
s = mid+1
if not flag:
if tree[mid] < q:
if mid < len(tree) - 1:
ans.append([tree[mid],tree[mid+1]])
else:
ans.append([tree[mid],-1])
elif tree[mid] > q:
if mid > 0:
ans.append([tree[mid-1],tree[mid]])
else:
ans.append([-1,tree[mid]])
return ans
O(N + M log N)
O(N): 트리를 배열로 변환 (노드 개수 N)
O(log N): 각 쿼리당 이진 탐색
O(N): 배열 tree에 노드를 저장