Skip to content

Commit 0765825

Browse files
authored
Merge pull request #218 from LetMeFly666/0236
《236.二叉树的最近公共祖先》的位运算方法
2 parents 1ef0693 + cbbae31 commit 0765825

File tree

3 files changed

+195
-2
lines changed

3 files changed

+195
-2
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'''
2+
Author: LetMeFly
3+
Date: 2024-02-09 12:19:22
4+
LastEditors: LetMeFly
5+
LastEditTime: 2024-02-09 12:24:33
6+
'''
7+
# AC,93.83%,86.17%
8+
from typing import Optional
9+
10+
# Definition for a binary tree node.
11+
class TreeNode:
12+
def __init__(self, x):
13+
self.val = x
14+
self.left = None
15+
self.right = None
16+
17+
class Status:
18+
none = 0
19+
onlyP = 1
20+
onlyQ = 2
21+
both = 3
22+
23+
class Solution:
24+
def dfs(self, root: Optional[TreeNode], p: 'TreeNode', q: 'TreeNode') -> Status:
25+
if not root:
26+
return Status.none
27+
thisStatus = Status.none
28+
if root == p:
29+
thisStatus |= Status.onlyP
30+
if root == q:
31+
thisStatus |= Status.onlyQ
32+
thisStatus |= self.dfs(root.left, p, q) | self.dfs(root.right, p, q)
33+
if thisStatus == Status.both and not self.ans:
34+
self.ans = root
35+
return thisStatus
36+
37+
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
38+
self.ans = None
39+
self.dfs(root, p, q)
40+
return self.ans
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* @Author: LetMeFly
3+
* @Date: 2024-02-09 12:05:51
4+
* @LastEditors: LetMeFly
5+
* @LastEditTime: 2024-02-09 12:29:59
6+
*/
7+
#ifdef _WIN32
8+
#include "_[1,2]toVector.h"
9+
#endif
10+
11+
/**
12+
* Definition for a binary tree node.
13+
* struct TreeNode {
14+
* int val;
15+
* TreeNode *left;
16+
* TreeNode *right;
17+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
18+
* };
19+
*/
20+
typedef int Status; // 一个二进制位表示子树中是否有节点p和节点q
21+
#define NONE 0
22+
#define ONLYP 1
23+
#define ONLYQ 2
24+
#define BOTH 3
25+
26+
class Solution {
27+
private:
28+
TreeNode* ans;
29+
30+
Status dfs(TreeNode* root, TreeNode* p, TreeNode* q) {
31+
if (!root) {
32+
return NONE;
33+
}
34+
Status thisStatus = NONE;
35+
if (root == p) {
36+
thisStatus |= ONLYP;
37+
}
38+
if (root == q) {
39+
thisStatus |= ONLYQ;
40+
}
41+
thisStatus |= dfs(root->left, p, q) | dfs(root->right, p, q);
42+
if (thisStatus == BOTH && !ans) {
43+
ans = root;
44+
}
45+
return thisStatus;
46+
}
47+
48+
public:
49+
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
50+
ans = nullptr;
51+
dfs(root, p, q);
52+
return ans;
53+
}
54+
};

Solutions/LeetCode 0236.二叉树的最近公共祖先.md

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
22
title: 236.二叉树的最近公共祖先
33
date: 2022-09-09 14:42:04
4-
tags: [题解, LeetCode, 中等, 树, 深度优先搜索, 二叉树]
4+
tags: [题解, LeetCode, 中等, 树, 深度优先搜索, DFS, 二叉树, 位运算]
55
---
66

7-
# 【LetMeFly】236.二叉树的最近公共祖先
7+
# 【LetMeFly】236.二叉树的最近公共祖先:深度优先搜索(巧用位运算)
88

99
力扣题目链接:[https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/)
1010

@@ -120,5 +120,104 @@ public:
120120
};
121121
```
122122

123+
## 方法二::深度优先搜索 + 巧用位运算
124+
125+
正常深搜(DFS),深搜过程中使用一个“状态”表示“当前节点及其子节点中PQ的存在情况”。
126+
127+
这样,第一个满足$状态=PQ都存在$的节点就是要找的答案(最近公共祖先)。
128+
129+
**怎么表示“状态”呢?**
130+
131+
可以使用二进制(位运算),用一个二进制位表示子树中是否有节点p和节点q,例如:
132+
133+
+ 0($00_2$)表示PQ都不存在
134+
+ 1($01_2$)表示P存在Q不存在
135+
+ 2($10_2$)表示P不存在Q存在
136+
+ 3($11_2$)表示PQ都存在
137+
138+
这样,$当前节点状态 | 左子树状态 | 右子树状态$即为$当前子树状态$(其中$|$为或运算)
139+
140+
### AC代码
141+
142+
#### C++
143+
144+
```cpp
145+
typedef int Status; // 一个二进制位表示子树中是否有节点p和节点q
146+
#define NONE 0
147+
#define ONLYP 1
148+
#define ONLYQ 2
149+
#define BOTH 3
150+
151+
class Solution {
152+
private:
153+
TreeNode* ans;
154+
155+
Status dfs(TreeNode* root, TreeNode* p, TreeNode* q) {
156+
if (!root) {
157+
return NONE;
158+
}
159+
Status thisStatus = NONE;
160+
if (root == p) {
161+
thisStatus |= ONLYP;
162+
}
163+
if (root == q) {
164+
thisStatus |= ONLYQ;
165+
}
166+
thisStatus |= dfs(root->left, p, q) | dfs(root->right, p, q);
167+
if (thisStatus == BOTH && !ans) {
168+
ans = root;
169+
}
170+
return thisStatus;
171+
}
172+
173+
public:
174+
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
175+
ans = nullptr;
176+
dfs(root, p, q);
177+
return ans;
178+
}
179+
};
180+
```
181+
182+
#### Python
183+
184+
```python
185+
# # AC,93.83%,86.17%
186+
# from typing import Optional
187+
188+
# # Definition for a binary tree node.
189+
# class TreeNode:
190+
# def __init__(self, x):
191+
# self.val = x
192+
# self.left = None
193+
# self.right = None
194+
195+
class Status:
196+
none = 0
197+
onlyP = 1
198+
onlyQ = 2
199+
both = 3
200+
201+
class Solution:
202+
def dfs(self, root: Optional[TreeNode], p: 'TreeNode', q: 'TreeNode') -> Status:
203+
if not root:
204+
return Status.none
205+
thisStatus = Status.none
206+
if root == p:
207+
thisStatus |= Status.onlyP
208+
if root == q:
209+
thisStatus |= Status.onlyQ
210+
thisStatus |= self.dfs(root.left, p, q) | self.dfs(root.right, p, q)
211+
if thisStatus == Status.both and not self.ans:
212+
self.ans = root
213+
return thisStatus
214+
215+
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
216+
self.ans = None
217+
self.dfs(root, p, q)
218+
return self.ans
219+
220+
```
221+
123222
> 同步发文于CSDN,原创不易,转载请附上[原文链接](https://blog.tisfy.eu.org/2022/09/09/LeetCode%200236.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88/)~
124223
> Tisfy:[https://letmefly.blog.csdn.net/article/details/126782886](https://letmefly.blog.csdn.net/article/details/126782886)

0 commit comments

Comments
 (0)