Skip to content

Commit 0ea731e

Browse files
author
weiy
committed
convert sorted list to binary search tree medium
1 parent 4e773e8 commit 0ea731e

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed
+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
"""
2+
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
3+
4+
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
5+
6+
Example:
7+
8+
Given the sorted linked list: [-10,-3,0,5,9],
9+
10+
One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:
11+
12+
0
13+
/ \
14+
-3 9
15+
/ /
16+
-10 5
17+
18+
19+
这次给的是一个排序过的链表,链表和数组有所不同,链表的话无法使用索引,或者说使用索引所需要的时间是 O(n) 并非 O(1)。
20+
当然可以把链表转换成一个数组然后按照数组的方法去解,这样不会出错,时间复杂度上也是同样的,就是空间复杂度上要高一些。
21+
22+
我自己的话没想到其他的思路:
23+
在Discuss里看到一个 Java 的思路,觉得非常棒:
24+
25+
前面我们分析过这其实就是个中序遍历的结果,按照这个思路,如果能按照中序遍历逆推回去,即可得到一颗完整的高度平衡的二叉搜索树。
26+
27+
这个思路也是这样的,在做二叉树的中序遍历时用递归一般这样写:
28+
```
29+
if root.left:
30+
recursive(root.left)
31+
root.val
32+
if root.right:
33+
recursive(root.right)
34+
35+
```
36+
如果我们能找到left的头,并一直持续到right的尾,即可得到一颗二叉搜索树,这棵树可能并不会与原来的相同。
37+
38+
如:
39+
中序结果是:
40+
[-1, 1, 2, 3]
41+
这颗树可能是:
42+
1
43+
/ \
44+
-1 2
45+
\
46+
3
47+
48+
也可以是:
49+
2
50+
/ \
51+
1 3
52+
/
53+
-1
54+
那就按原来的数组中的方法:
55+
如果要从中序遍历的结果生成二叉树,首先需要获取的是 mid 中位,找到它的根。剩下的也是不断找到根。
56+
[-10,-3,0,5,9]
57+
1. 第一步先找一下链表的长度。
58+
2. 第二步则给函数说左有几个,右有几个。
59+
60+
左边有几个的话很简单:
61+
直接 length // 2即可,地板除的话会舍弃。 比如如果有4个数据。 4//2之后左边的还剩下 两个 [0,1]
62+
63+
右边的话:
64+
需要原来的长度 减去左边的长度 再减去 这个的根得知。
65+
66+
这样不断递归至 size 为 0 即为左子树的头,与右子树的尾。
67+
[-10,-3,0,5,9]
68+
69+
1. size = 5
70+
left = 5//2 = 2 [-10,-3]
71+
right = 5 - left - 1 = 5 - 2 - 1 = 2 [5, 9]
72+
73+
2. size = 1.left = 2
74+
left = 2//1 = 1 [-10]
75+
right = 2 - left - 1 = 2 - 1 -1 = 0 []
76+
77+
3. size = 2.left = 1
78+
left = 1 // 2 = 0
79+
right = 1 - 0 - 1 = 0
80+
这一步开始返回链表的第一个值 -10 作为 2 里左节点的val.之后返回到2
81+
2. 则把自己的节点值覆盖为链表中下一个值 -3。 之后返回到1.
82+
1. 则把自己的节点值覆盖为链表中的下一个值 0。 之后开始right的递归。同样的操作。
83+
---
84+
4. size = 1.right = 2
85+
left = 2//1 = 1 [5]
86+
right = 2 - left - 1 = 2 -1 -1 =0 []
87+
5. size = 4.left = 1
88+
left = 1 // 2 = 0 []
89+
right = 1- 0 -1 = 0 []
90+
...
91+
92+
关键词:
93+
中序遍历,左右子树节点的个数。
94+
95+
beat 99%
96+
97+
测试地址:
98+
https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/description/
99+
100+
"""
101+
# Definition for singly-linked list.
102+
# class ListNode(object):
103+
# def __init__(self, x):
104+
# self.val = x
105+
# self.next = None
106+
107+
# Definition for a binary tree node.
108+
# class TreeNode(object):
109+
# def __init__(self, x):
110+
# self.val = x
111+
# self.left = None
112+
# self.right = None
113+
114+
class Solution(object):
115+
def sortedListToBST(self, head):
116+
"""
117+
:type head: ListNode
118+
:rtype: TreeNode
119+
"""
120+
size = 0
121+
122+
self.c_head = head
123+
124+
while head:
125+
size += 1
126+
head = head.next
127+
128+
def makeBSTByInorder(size):
129+
if not size:
130+
return
131+
132+
root = TreeNode(None)
133+
134+
root.left = makeBSTByInorder(size//2)
135+
root.val = self.c_head.val
136+
self.c_head = self.c_head.next
137+
root.right = makeBSTByInorder(size-size//2-1)
138+
139+
return root
140+
141+
return makeBSTByInorder(size)

0 commit comments

Comments
 (0)