티스토리 뷰

728x90
반응형

문제

동일한 값을 지닌 가장 긴 경로를 찾아라.

입력

image

출력

2

입력

image

출력

2

코드

class TreeNode:
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    result: int = 0

    def longestUnivaluePath(self, root: TreeNode):
        def dfs(node: TreeNode):
            if node is None:
                return 0

            left = dfs(node.left)
            right = dfs(node.right)

            if node.left and node.left.val == node.val:
                left += 1
            else:
                left = 0
            if node.right and node.right.val == node.val:
                right += 1
            else:
                right = 0

            self.result = max(self.result, left + right)
            return max(left, right)

        dfs(root)
        return self.result

풀이

루트 노드에서 DFS로 재귀 탐색을 진행하면서 리프에 도달하면 그때부터 백트래킹하면서 거리를 누적해나간다.

def dfs(node: TreeNode):
    ...
    left = dfs(node.left)
    right = dfs(node.right)

이렇게 재귀 호출로 내려가면 left, right는 각각 리프 노드에 이르러서 값을 리턴받게 된다. 더 이상 존재하지 않는 노드까지 내려가게 되면 다음과 같은 형태로 리턴한다.

if node is None:
    return 0

존재하지 않는 노드까지 내려가게 되면 거리 0을 리턴한다. 이제 이 값이 점점 백트래킹 되면서 증가할 것이다. 이 문제는 동일 값 여부를 판별해 거리를 계산하는 문제이기 때문에, 다음과 같이 자식 노드가 동일한 값인지 확인하는 과정이 필요하다.

if node.left and node.left.val == node.val:
    left += 1
else:
    left = 0
if node.right and node.right.val == node.val:
    right += 1
else:
    right = 0

왼쪽과 오른쪽 자식 노드를 각각 확인해서 현재 노드, 그러니까 부모 노드와 동일한 경우 각각 거리를 1 증가한다. 이제 다음과 같이 왼쪽 자식과 오른쪽 자식 노드 간 거리의 합을 결과로 한다.

result = max(result, left + right)

합이 가장 큰 값을 최종 결과로 한다. 이제 다음번 백트래킹 시 계산을 위해 앞서 문제와 유사하게 상태값을 셋팅해서 부모 노드로 올려야 한다. 다음과 같이 부모 노드를 위해 현재까지의 거리를 리턴해준다.

return max(left, right)

현재 노드는 양쪽 자식 노드를 모두 연결할 수 있지만 현재 노드의 부모 노드에서는 지금의 양쪽 자식 노드를 모두 연결할 수 없다. 단방향이므로 양쪽 자식 노드 중 어느 한쪽 자식만 택할 수 있으며, 이는 트리의 특징이기도 하다. 따라서 둘중 큰 값을 상태 값으로 리턴해준다. 어차피 한 군데만 방문할 수 있다면 더 큰쪽을 방문하는 게 낫기 때문이다.

헷갈렸던 부분

result = max(result, left + right)

left 자식 노드, right 자식 노드와 현재 노드를 비교하여 left, right를 업데이트 해준 뒤, 그 업데이트 된 값을 더해서 result를 계산. 즉, 예제의 루트노드로 보자면 0 + 2로 result가 계산된다.

return max(left, right)

거리 자체가 한가지 길로 계속 이어져야지 left, right 두가지길로 나뉘어지면 안된다.



출처
파이썬 알고리즘 인터뷰 (글 : 박상길 그림 : 정진호) [책만]

728x90
반응형
댓글
반응형
250x250
글 보관함
최근에 달린 댓글
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Total
Today
Yesterday
링크