|
56 | 56 |
|
57 | 57 | ## 解法
|
58 | 58 |
|
59 |
| -### 方法一 |
| 59 | +### 方法一:哈希表 |
| 60 | + |
| 61 | +我们用一个哈希表 $vis$ 记录从节点 $p$ 开始到根节点的路径上的所有节点,接下来从节点 $q$ 开始往根节点方向遍历,如果遇到一个节点存在于哈希表 $vis$ 中,那么该节点就是 $p$ 和 $q$ 的最近公共祖先节点,直接返回即可。 |
| 62 | + |
| 63 | +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点数。 |
| 64 | + |
| 65 | +<!-- tabs:start --> |
| 66 | + |
| 67 | +```python |
| 68 | +""" |
| 69 | +# Definition for a Node. |
| 70 | +class Node: |
| 71 | + def __init__(self, val): |
| 72 | + self.val = val |
| 73 | + self.left = None |
| 74 | + self.right = None |
| 75 | + self.parent = None |
| 76 | +""" |
| 77 | + |
| 78 | + |
| 79 | +class Solution: |
| 80 | + def lowestCommonAncestor(self, p: "Node", q: "Node") -> "Node": |
| 81 | + vis = set() |
| 82 | + node = p |
| 83 | + while node: |
| 84 | + vis.add(node) |
| 85 | + node = node.parent |
| 86 | + node = q |
| 87 | + while node not in vis: |
| 88 | + node = node.parent |
| 89 | + return node |
| 90 | +``` |
| 91 | + |
| 92 | +```java |
| 93 | +/* |
| 94 | +// Definition for a Node. |
| 95 | +class Node { |
| 96 | + public int val; |
| 97 | + public Node left; |
| 98 | + public Node right; |
| 99 | + public Node parent; |
| 100 | +}; |
| 101 | +*/ |
| 102 | + |
| 103 | +class Solution { |
| 104 | + public Node lowestCommonAncestor(Node p, Node q) { |
| 105 | + Set<Node> vis = new HashSet<>(); |
| 106 | + for (Node node = p; node != null; node = node.parent) { |
| 107 | + vis.add(node); |
| 108 | + } |
| 109 | + for (Node node = q;; node = node.parent) { |
| 110 | + if (!vis.add(node)) { |
| 111 | + return node; |
| 112 | + } |
| 113 | + } |
| 114 | + } |
| 115 | +} |
| 116 | +``` |
| 117 | + |
| 118 | +```cpp |
| 119 | +/* |
| 120 | +// Definition for a Node. |
| 121 | +class Node { |
| 122 | +public: |
| 123 | + int val; |
| 124 | + Node* left; |
| 125 | + Node* right; |
| 126 | + Node* parent; |
| 127 | +}; |
| 128 | +*/ |
| 129 | + |
| 130 | +class Solution { |
| 131 | +public: |
| 132 | + Node* lowestCommonAncestor(Node* p, Node* q) { |
| 133 | + unordered_set<Node*> vis; |
| 134 | + for (Node* node = p; node; node = node->parent) { |
| 135 | + vis.insert(node); |
| 136 | + } |
| 137 | + for (Node* node = q;; node = node->parent) { |
| 138 | + if (vis.count(node)) { |
| 139 | + return node; |
| 140 | + } |
| 141 | + } |
| 142 | + } |
| 143 | +}; |
| 144 | +``` |
| 145 | +
|
| 146 | +```go |
| 147 | +/** |
| 148 | + * Definition for Node. |
| 149 | + * type Node struct { |
| 150 | + * Val int |
| 151 | + * Left *Node |
| 152 | + * Right *Node |
| 153 | + * Parent *Node |
| 154 | + * } |
| 155 | + */ |
| 156 | +
|
| 157 | +func lowestCommonAncestor(p *Node, q *Node) *Node { |
| 158 | + vis := map[*Node]bool{} |
| 159 | + for node := p; node != nil; node = node.Parent { |
| 160 | + vis[node] = true |
| 161 | + } |
| 162 | + for node := q; ; node = node.Parent { |
| 163 | + if vis[node] { |
| 164 | + return node |
| 165 | + } |
| 166 | + } |
| 167 | +} |
| 168 | +``` |
| 169 | + |
| 170 | +```ts |
| 171 | +/** |
| 172 | + * Definition for a binary tree node. |
| 173 | + * class Node { |
| 174 | + * val: number |
| 175 | + * left: Node | null |
| 176 | + * right: Node | null |
| 177 | + * parent: Node | null |
| 178 | + * constructor(val?: number, left?: Node | null, right?: Node | null, parent?: Node | null) { |
| 179 | + * this.val = (val===undefined ? 0 : val) |
| 180 | + * this.left = (left===undefined ? null : left) |
| 181 | + * this.right = (right===undefined ? null : right) |
| 182 | + * this.parent = (parent===undefined ? null : parent) |
| 183 | + * } |
| 184 | + * } |
| 185 | + */ |
| 186 | + |
| 187 | +function lowestCommonAncestor(p: Node | null, q: Node | null): Node | null { |
| 188 | + const vis: Set<Node> = new Set(); |
| 189 | + for (let node = p; node; node = node.parent) { |
| 190 | + vis.add(node); |
| 191 | + } |
| 192 | + for (let node = q; ; node = node.parent) { |
| 193 | + if (vis.has(node)) { |
| 194 | + return node; |
| 195 | + } |
| 196 | + } |
| 197 | +} |
| 198 | +``` |
| 199 | + |
| 200 | +<!-- tabs:end --> |
| 201 | + |
| 202 | +### 方法二:双指针 |
| 203 | + |
| 204 | +我们可以用两个指针 $a$ 和 $b$ 分别指向节点 $p$ 和 $q$,然后分别往根节点方向遍历,当 $a$ 和 $b$ 相遇时,就是 $p$ 和 $q$ 的最近公共祖先节点。否则,如果指针 $a$ 遍历到了根节点,那么我们就让它指向节点 $q$,指针 $b$ 同理。这样,当两个指针相遇时,就是 $p$ 和 $q$ 的最近公共祖先节点。 |
| 205 | + |
| 206 | +时间复杂度 $O(n)$,其中 $n$ 是二叉树的节点数。空间复杂度 $O(1)$。 |
60 | 207 |
|
61 | 208 | <!-- tabs:start -->
|
62 | 209 |
|
@@ -159,6 +306,33 @@ func lowestCommonAncestor(p *Node, q *Node) *Node {
|
159 | 306 | }
|
160 | 307 | ```
|
161 | 308 |
|
| 309 | +```ts |
| 310 | +/** |
| 311 | + * Definition for a binary tree node. |
| 312 | + * class Node { |
| 313 | + * val: number |
| 314 | + * left: Node | null |
| 315 | + * right: Node | null |
| 316 | + * parent: Node | null |
| 317 | + * constructor(val?: number, left?: Node | null, right?: Node | null, parent?: Node | null) { |
| 318 | + * this.val = (val===undefined ? 0 : val) |
| 319 | + * this.left = (left===undefined ? null : left) |
| 320 | + * this.right = (right===undefined ? null : right) |
| 321 | + * this.parent = (parent===undefined ? null : parent) |
| 322 | + * } |
| 323 | + * } |
| 324 | + */ |
| 325 | + |
| 326 | +function lowestCommonAncestor(p: Node | null, q: Node | null): Node | null { |
| 327 | + let [a, b] = [p, q]; |
| 328 | + while (a != b) { |
| 329 | + a = a.parent ?? q; |
| 330 | + b = b.parent ?? p; |
| 331 | + } |
| 332 | + return a; |
| 333 | +} |
| 334 | +``` |
| 335 | + |
162 | 336 | <!-- tabs:end -->
|
163 | 337 |
|
164 | 338 | <!-- end -->
|
0 commit comments