Skip to content

Commit 9df92b2

Browse files
author
robot
committed
fix: 时间复杂度
1 parent 8a9b034 commit 9df92b2

File tree

1 file changed

+106
-4
lines changed

1 file changed

+106
-4
lines changed

thinkings/balanced-tree.md

+106-4
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,57 @@ class Solution:
191191

192192
### 代码
193193

194-
代码支持: Python3
194+
### 代码
195195

196-
Python3 Code:
196+
代码支持:JS,Java,Python,C++
197+
198+
JS Code
199+
200+
```js
201+
var sortedListToBST = function (head) {
202+
if (!head) return null;
203+
return dfs(head, null);
204+
};
205+
206+
function dfs(head, tail) {
207+
if (head == tail) return null;
208+
let fast = head;
209+
let slow = head;
210+
while (fast != tail && fast.next != tail) {
211+
fast = fast.next.next;
212+
slow = slow.next;
213+
}
214+
let root = new TreeNode(slow.val);
215+
root.left = dfs(head, slow);
216+
root.right = dfs(slow.next, tail);
217+
return root;
218+
}
219+
```
220+
221+
Java Code:
222+
223+
```java
224+
class Solution {
225+
public TreeNode sortedListToBST(ListNode head) {
226+
if(head == null) return null;
227+
return dfs(head,null);
228+
}
229+
private TreeNode dfs(ListNode head, ListNode tail){
230+
if(head == tail) return null;
231+
ListNode fast = head, slow = head;
232+
while(fast != tail && fast.next != tail){
233+
fast = fast.next.next;
234+
slow = slow.next;
235+
}
236+
TreeNode root = new TreeNode(slow.val);
237+
root.left = dfs(head, slow);
238+
root.right = dfs(slow.next, tail);
239+
return root;
240+
}
241+
}
242+
```
243+
244+
Python Code:
197245

198246
```py
199247
class Solution:
@@ -216,10 +264,64 @@ class Solution:
216264
return node
217265
```
218266

267+
C++ Code:
268+
269+
```cpp
270+
class Solution {
271+
public:
272+
TreeNode* sortedListToBST(ListNode* head) {
273+
if (head == nullptr) return nullptr;
274+
return sortedListToBST(head, nullptr);
275+
}
276+
TreeNode* sortedListToBST(ListNode* head, ListNode* tail) {
277+
if (head == tail) return nullptr;
278+
279+
ListNode* slow = head;
280+
ListNode* fast = head;
281+
282+
while (fast != tail && fast->next != tail) {
283+
slow = slow->next;
284+
fast = fast->next->next;
285+
}
286+
287+
TreeNode* root = new TreeNode(slow->val);
288+
root->left = sortedListToBST(head, slow);
289+
root->right = sortedListToBST(slow->next, tail);
290+
return root;
291+
}
292+
};
293+
```
294+
219295
**复杂度分析**
220296

221-
- 时间复杂度:由于每个节点最多被访问一次,因此总的时间复杂度为 $O(N)$,其中 $N$ 为链表长度。
222-
- 空间复杂度:由于使用了递归,这里的空间复杂度的瓶颈在栈空间,因此空间复杂度为 $O(h)$,其中 $h$ 为树的高度。同时由于是平衡二叉树,因此 $h$ 就是 $log N$。
297+
令 n 为链表长度。
298+
299+
- 时间复杂度:递归树的深度为 $logn$,每一层的基本操作数为 $n$,因此总的时间复杂度为$O(nlogn)$
300+
- 空间复杂度:空间复杂度为$O(logn)$
301+
302+
有的同学不太会分析递归的时间复杂度和空间复杂度,我们在这里给大家再次介绍一下。
303+
304+
![](https://tva1.sinaimg.cn/large/008i3skNly1gqmduc0j3dj314d0jk7ju.jpg)
305+
306+
首先我们尝试画出如下的递归树。由于递归树的深度为 $logn$ 因此空间复杂度就是 $logn$ \* 递归函数内部的空间复杂度,由于递归函数内空间复杂度为 $O(1)$,因此总的空间复杂度为 $O(logn)$。
307+
308+
时间复杂度稍微困难一点点。之前西法在先导篇给大家说过:**如果有递归那就是:递归树的节点数 \* 递归函数内部的基础操作数**。而这句话的前提是所有递归函数内部的基本操作数是一样的,这样才能直接乘。而这里递归函数的基本操作数不一样。
309+
310+
不过我们发现递归树内部每一层的基本操作数都是固定的, 为啥固定已经在图上给大家算出来了。因此总的空间复杂度其实可以通过**递归深度 \* 每一层基础操作数**计算得出,也就是 $nlogn$。 类似的技巧可以用于归并排序的复杂度分析中。
311+
312+
另外大家也直接可以通过公式推导得出。对于这道题来说,设基本操作数 T(n),那么就有 T(n) = T(n/2) \* 2 + n/2,推导出来 T(n) 大概是 nlogn。这应该高中的知识。
313+
具体推导过程如下:
314+
315+
$$
316+
317+
T(n) = T(n/2) _ 2 + n/2 =
318+
\frac{n}{2} + 2 _ (\frac{n}{2}) ^ 2 + 2 ^ 2 _ (\frac{n}{2}) ^ 3 + ...
319+
= logn _ \frac{n}{2}
320+
321+
322+
$$
323+
324+
类似地,如果递推公式为 T(n) = T(n/2) \* 2 + 1 ,那么 T(n) 大概就是 logn。
223325

224326
## 1382. 将二叉搜索树变平衡(中等)
225327

0 commit comments

Comments
 (0)