# 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:
prev = -sys.maxsize
result = sys.maxsize
#재귀 구조 중위 순회 비교 결과
def minDiffInBST(self, root: TreeNode) -> int:
if root.left:
self.minDiffInBST(root.left)
self.result = min(self.result, root.val - self.prev)
self.prev = root.val
if root.right:
self.minDiffInBST(root.right)
return self.result
값의 차이가 가장 작은 노드를 찾으려면 어디와 어디 노드를 비교해야 하는지 생각해보자.
이 경우 루트 D와 가장 차이가 작을 수 있는 노드는 딱 2개 노드만 가능한데, 어디와 어디일까?
이외에는 항상 이들 노드보다 값의 차이가 클 것이다.
D -> B의 차이는 D -> C보다는 무조건 크다. 왼쪽으로 갈수록 값이 더 작아지기 때문이다.
D -> A, D -> F 도 마찬가지다. D -> C보다 작아질 수 없다.
따라서 D -> B 부터는 제외하고, 그렇다면 D -> E 하위 노드들에 가능성이 있는데, 이 중에서도 D -> H는 D -> E보다 무조건 크기 때문에 마찬가지로 배제한다.
오른쪽 자식은 더 큰 값을 지니기 때문에 이 경우 D -> I가 가장 작은 값이 될 수 있다.
물론 항상 정답은 아닐 수도 있다. 왜냐면 D -> G가 의외로 가장 작은 값이 될 수 있기 때문이다.
<두 노드 간 값의 차이가 가장 작은 노드 계산>
두 노드 간 값의 차이가 가장 작은 노드를 계산하기 위한 순서를 파란 글씨로 표시했다.
루트인 8은 7과 12 두 군데를 비교해보는데, 앞서 설명한 D -> I, D -> G인 비교 대상과 동일함을 확인할 수 있다.
# 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 minDiffInBST(self, root: TreeNode) -> int:
prev = -sys.maxsize
result = sys.maxsize
stack = []
node = root
while stack or node:
while node:
stack.append(node)
node = node.left
node = stack.pop()
result = min(result, node.val - prev)
prev = node.val
node = node.right
return result
추가 장점은 재귀일 때는 prev
와 result
를 클래스 멤버 변수로 선언했지만, 반복 구조에서는 한 함수 내에서 처리할 수 있기 때문에 함수 내 변수로 선언이 가능하다는 점이다.
DFS 풀이인 만큼 스택을 사용했고, 오른쪽 자식 노드를 택하기 전에 비교하는 형태로 재귀와 동일하게 중위 순회로 풀이했다.