Skip to content

Commit 367e634

Browse files
authored
feat: add solutions to lc/lcci problems (doocs#2648)
lc No.285 & lcci No.04.06.Successor
1 parent f377b03 commit 367e634

File tree

18 files changed

+371
-418
lines changed

18 files changed

+371
-418
lines changed

lcci/04.06.Successor/README.md

+71-131
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,18 @@
3535

3636
## 解法
3737

38-
### 方法一
38+
### 方法一:二分搜索
39+
40+
二叉搜索树的中序遍历是一个升序序列,因此可以使用二分搜索的方法。
41+
42+
二叉搜索树节点 $p$ 的中序后继节点满足:
43+
44+
1. 中序后继的节点值大于 $p$ 的节点值
45+
2. 中序后继是所有大于 $p$ 的节点中值最小的节点
46+
47+
因此,对于当前节点 $root$,如果 $root.val \gt p.val$,则 $root$ 可能是 $p$ 的中序后继节点,将 $root$ 记为 $ans$,然后搜索左子树,即 $root = root.left$;如果 $root.val \leq p.val$,则 $root$ 不能是 $p$ 的中序后继节点,搜索右子树,即 $root = root.right$。
48+
49+
时间复杂度 $O(h)$,其中 $h$ 为二叉搜索树的高度。空间复杂度 $O(1)$。
3950

4051
<!-- tabs:start -->
4152

@@ -49,19 +60,14 @@
4960

5061

5162
class Solution:
52-
def inorderSuccessor(self, root: TreeNode, p: TreeNode) -> TreeNode:
53-
def dfs(root):
54-
if root is None:
55-
return
56-
dfs(root.left)
57-
nonlocal ans, prev
58-
if prev == p:
63+
def inorderSuccessor(self, root: TreeNode, p: TreeNode) -> Optional[TreeNode]:
64+
ans = None
65+
while root:
66+
if root.val > p.val:
5967
ans = root
60-
prev = root
61-
dfs(root.right)
62-
63-
ans = prev = None
64-
dfs(root)
68+
root = root.left
69+
else:
70+
root = root.right
6571
return ans
6672
```
6773

@@ -76,28 +82,17 @@ class Solution:
7682
* }
7783
*/
7884
class Solution {
79-
private TreeNode prev;
80-
private TreeNode p;
81-
private TreeNode ans;
82-
8385
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
84-
prev = null;
85-
ans = null;
86-
this.p = p;
87-
dfs(root);
88-
return ans;
89-
}
90-
91-
private void dfs(TreeNode root) {
92-
if (root == null) {
93-
return;
94-
}
95-
dfs(root.left);
96-
if (prev == p) {
97-
ans = root;
86+
TreeNode ans = null;
87+
while (root != null) {
88+
if (root.val > p.val) {
89+
ans = root;
90+
root = root.left;
91+
} else {
92+
root = root.right;
93+
}
9894
}
99-
prev = root;
100-
dfs(root.right);
95+
return ans;
10196
}
10297
}
10398
```
@@ -114,23 +109,18 @@ class Solution {
114109
*/
115110
class Solution {
116111
public:
117-
TreeNode* prev;
118-
TreeNode* p;
119-
TreeNode* ans;
120-
121112
TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
122-
this->p = p;
123-
dfs(root);
113+
TreeNode* ans = nullptr;
114+
while (root) {
115+
if (root->val > p->val) {
116+
ans = root;
117+
root = root->left;
118+
} else {
119+
root = root->right;
120+
}
121+
}
124122
return ans;
125123
}
126-
127-
void dfs(TreeNode* root) {
128-
if (!root) return;
129-
dfs(root->left);
130-
if (prev == p) ans = root;
131-
prev = root;
132-
dfs(root->right);
133-
}
134124
};
135125
```
136126
@@ -143,91 +133,46 @@ public:
143133
* Right *TreeNode
144134
* }
145135
*/
146-
func inorderSuccessor(root *TreeNode, p *TreeNode) *TreeNode {
147-
var prev, ans *TreeNode
148-
var dfs func(root *TreeNode)
149-
dfs = func(root *TreeNode) {
150-
if root == nil {
151-
return
152-
}
153-
dfs(root.Left)
154-
if prev == p {
136+
func inorderSuccessor(root *TreeNode, p *TreeNode) (ans *TreeNode) {
137+
for root != nil {
138+
if root.Val > p.Val {
155139
ans = root
140+
root = root.Left
141+
} else {
142+
root = root.Right
156143
}
157-
prev = root
158-
dfs(root.Right)
159144
}
160-
dfs(root)
161-
return ans
145+
return
162146
}
163147
```
164148

165-
```js
149+
```ts
166150
/**
167151
* Definition for a binary tree node.
168-
* function TreeNode(val) {
169-
* this.val = val;
170-
* this.left = this.right = null;
152+
* class TreeNode {
153+
* val: number
154+
* left: TreeNode | null
155+
* right: TreeNode | null
156+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
157+
* this.val = (val===undefined ? 0 : val)
158+
* this.left = (left===undefined ? null : left)
159+
* this.right = (right===undefined ? null : right)
160+
* }
171161
* }
172162
*/
173-
/**
174-
* @param {TreeNode} root
175-
* @param {TreeNode} p
176-
* @return {TreeNode}
177-
*/
178-
var inorderSuccessor = function (root, p) {
179-
if (root == null) {
180-
return root;
181-
}
182-
const { val, left, right } = root;
183-
const res = inorderSuccessor(left, p);
184-
if (res != null) {
185-
return res;
186-
}
187-
if (val > p.val) {
188-
return root;
189-
}
190-
return inorderSuccessor(right, p);
191-
};
192-
```
193-
194-
<!-- tabs:end -->
195-
196-
### 方法二
197163

198-
<!-- tabs:start -->
199-
200-
```cpp
201-
/**
202-
* Definition for a binary tree node.
203-
* struct TreeNode {
204-
* int val;
205-
* TreeNode *left;
206-
* TreeNode *right;
207-
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
208-
* };
209-
*/
210-
class Solution {
211-
public:
212-
TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
213-
stack<TreeNode*> stk;
214-
TreeNode* cur = root;
215-
while (cur != nullptr || !stk.empty()) {
216-
if (cur == nullptr) {
217-
cur = stk.top();
218-
stk.pop();
219-
if (cur->val > p->val) {
220-
return cur;
221-
}
222-
cur = cur->right;
223-
} else {
224-
stk.push(cur);
225-
cur = cur->left;
226-
}
164+
function inorderSuccessor(root: TreeNode | null, p: TreeNode | null): TreeNode | null {
165+
let ans: TreeNode | null = null;
166+
while (root) {
167+
if (root.val > p.val) {
168+
ans = root;
169+
root = root.left;
170+
} else {
171+
root = root.right;
227172
}
228-
return cur;
229173
}
230-
};
174+
return ans;
175+
}
231176
```
232177

233178
```js
@@ -244,21 +189,16 @@ public:
244189
* @return {TreeNode}
245190
*/
246191
var inorderSuccessor = function (root, p) {
247-
const stack = [];
248-
let cur = root;
249-
while (cur != null || stack.length !== 0) {
250-
if (cur == null) {
251-
cur = stack.pop();
252-
if (cur.val > p.val) {
253-
return cur;
254-
}
255-
cur = cur.right;
192+
let ans = null;
193+
while (root) {
194+
if (root.val > p.val) {
195+
ans = root;
196+
root = root.left;
256197
} else {
257-
stack.push(cur);
258-
cur = cur.left;
198+
root = root.right;
259199
}
260200
}
261-
return cur;
201+
return ans;
262202
};
263203
```
264204

0 commit comments

Comments
 (0)