未验证 提交 a07a93f0 编写于 作者: K KEQI HUANG 提交者: GitHub

Update 255._Verify_Preorder_Sequence_in_Binary_Search_Tree.md

上级 6daa16d6
......@@ -10,10 +10,8 @@ Medium
思路:
思路
二叉搜索树先序遍历序列的特点是降序的部分一定是向左走的,一旦开始升序说明开始向右走了,
则上一个降序的点则限定了后面的数的最小值。如果继续降序,说明又向左走了,这样等到下次向右走得时候也要再次更新最小值。
这道题让给了我们一个一维数组,让我们验证其是否为一个二叉搜索树的先序遍历出的顺序,我们都知道二叉搜索树的性质是左<根<右,如果用中序遍历得到的结果就是有序数组,而先序遍历的结果就不是有序数组了,但是难道一点规律都没有了吗,其实规律还是有的,根据二叉搜索树的性质,当前节点的值一定大于其左子树中任何一个节点值,而且其右子树中的任何一个节点值都不能小于当前节点值,那么我们可以用这个性质来验证,举个例子,比如下面这棵二叉搜索树:
```
10
/ \
......@@ -24,7 +22,7 @@ Medium
preorder:[10, 5, 2, 6, 12]
```
如这个例子,我们在10的位置是没有最小值限定的,然后降序走到5,依然没有最小值,降序走到2,依然没有,然后开始升序了,遇到6,这时候之后的数字一定大于2,同时也大于5,所以最小值更新为之前遍历过的,且比当前数稍微小一点的那个数。这里我们可以用一个栈来暂存之前的路径,所以升序时就是将栈中元素不断pop出来直到栈顶大于当前数,而最小值就是最后一个pop出来的数,最后再把该数push进去。对于降序的时候,直接向里面push就行了。这样,序列无效的条件就是违反了这个最小值的限定。
如这个例子,我们先设一个最小值min_num,然后遍历数组,如果当前值小于这个最小值min_num,返回false,对于根节点,我们将其压入栈中,然后往后遍历,如果遇到的数字比栈顶元素小,说明是其左子树的点,继续压入栈中,直到遇到的数字比栈顶元素大,那么就是右边的值了,我们需要找到是哪个节点的右子树,所以我们更新low值并删掉栈顶元素,然后继续和下一个栈顶元素比较,如果还是大于,则继续更新low值和删掉栈顶,直到栈为空或者当前栈顶元素大于当前值停止,压入当前值,这样如果遍历完整个数组之前都没有返回false的话,最后返回true即可
参考[Ethan Li 的技术专栏](https://segmentfault.com/a/1190000003874375)
......@@ -56,13 +54,13 @@ class Solution(object):
:rtype: bool
"""
# stack = preorder[:i], reuse preorder as stack
lower = -1 << 31
min_num = -1 << 31
i = 0
for x in preorder:
if x < lower:
if x < min_num:
return False
while i > 0 and x > preorder[i - 1]:
lower = preorder[i - 1]
min_num = preorder[i - 1]
i -= 1
preorder[i] = x
i += 1
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册