|
| 1 | +"""TC: O(n), SC: O(h) |
| 2 | +
|
| 3 | +
|
| 4 | +아이디어: |
| 5 | +- 각 노드를 부모, 혹은 자식 노드의 관점에서 분석할 수 있다. |
| 6 | +- 부모 노드의 관점에서 경로를 만들때: |
| 7 | + - 부모 노드는 양쪽 자식 노드에 연결된 경로를 잇는 다리 역할을 할 수 있다. |
| 8 | + - 이때 자식 노드는 |
| 9 | + - 경로에 포함되지 않아도 된다. 이 경우 path에 0만큼 기여하는 것으로 볼 수 있다. |
| 10 | + - 자식 노드의 두 자식 노드 중 한 쪽의 경로와 부모 노드를 이어주는 역할을 한다. |
| 11 | + 아래서 좀 더 자세히 설명. |
| 12 | +- 자식 노드의 관점에서 경로를 만들때: |
| 13 | + - 자식 노드는 부모 노드와 연결될 수 있어야 한다. |
| 14 | + - 그렇기 때문에 자신의 자식 노드 중 한 쪽과만 연결되어있을 수 있다. 만약 부모 노드와 |
| 15 | + 본인의 양쪽 자식 노드 모두와 연결되어 있으면 이 노드가 세 갈림길이 되어서 경로를 만들 |
| 16 | + 수 없기 때문. |
| 17 | +- 위의 분석을 통해 최대 경로를 만들고 싶다면, 다음의 함수를 root를 기준으로 재귀적으로 실행한다. |
| 18 | + - 특정 node가 부모 노드가 되었다고 했을때 본인의 값에 두 자식의 max(최대 경로, 0) 값을 더해서 |
| 19 | + 경로를 만들어본다. 이 값이 기존 solution보다 클 경우 solution을 업데이트. |
| 20 | + - 특정 node가 자식 노드가 될 경우 본인의 두 자식 중 더 큰 경로를 부모에 제공해야 한다. |
| 21 | + 본인의 값에 max(왼쪽 경로, 오른쪽 경로)을 더해서 리턴. |
| 22 | +
|
| 23 | +SC: |
| 24 | +- solution값을 관리한다. O(1). |
| 25 | +- 호출 스택은 트리의 높이만큼 쌓일 수 있다. O(h). |
| 26 | +- 종합하면 O(h). |
| 27 | +
|
| 28 | +TC: |
| 29 | +- 각 노드에서 O(1) 시간이 소요되는 작업 수행. |
| 30 | +- 모든 노드에 접근하므로 O(n). |
| 31 | +""" |
| 32 | + |
| 33 | + |
| 34 | +# Definition for a binary tree node. |
| 35 | +# class TreeNode: |
| 36 | +# def __init__(self, val=0, left=None, right=None): |
| 37 | +# self.val = val |
| 38 | +# self.left = left |
| 39 | +# self.right = right |
| 40 | +class Solution: |
| 41 | + def maxPathSum(self, root: Optional[TreeNode]) -> int: |
| 42 | + sol = [-1001] # 노드의 최소값보다 1 작은 값. 현 문제 세팅에서 -inf 역할을 함. |
| 43 | + |
| 44 | + def try_get_best_path(node): |
| 45 | + if node is None: |
| 46 | + # 노드가 비어있을때 경로 없음. 이때 이 노드로부터 얻을 수 있는 최대 경로 값을 |
| 47 | + # 0으로 칠 수 있다. |
| 48 | + return 0 |
| 49 | + |
| 50 | + # 왼쪽, 오른쪽 노드로부터 얻을 수 있는 최대 경로 값. |
| 51 | + l = max(try_get_best_path(node.left), 0) |
| 52 | + r = max(try_get_best_path(node.right), 0) |
| 53 | + |
| 54 | + # 현 노드를 다리 삼아서 양쪽 자식 노드의 경로를 이었을때 나올 수 있는 경로 값이 |
| 55 | + # 최대 경로일 수도 있다. 이 값을 현 솔루션과 비교해서 업데이트 해준다. |
| 56 | + sol[0] = max(node.val + l + r, sol[0]) |
| 57 | + |
| 58 | + # 현 노드의 부모 노드가 `이 노드를 통해 얻을 수 있는 최대 경로 값`으로 사용할 값을 리턴. |
| 59 | + return node.val + max(l, r) |
| 60 | + |
| 61 | + try_get_best_path(root) |
| 62 | + return sol[0] |
0 commit comments