剑指offer(九) 栈的压入弹出序列,从上往下打印二叉树,二叉搜索树的后序遍历序列

栈的压入、弹出序列

题目描述

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

解题思路:

设置三个栈,一个pushV,一个popV, 一个辅助stack,把数据从pushv到stack中压,如果压入stack中的元素与popv栈首元素相同,则pushV ,popV直接出栈,不必压入stack,直到pushV中没有元素,判断stack中出栈元素和popv中出栈是否一致,如果popv中元素全部弹出,说明弹出序列一致,两个序列长度相同,就结束了。

代码:

# -*- coding:utf-8 -*-
class Solution:
    def IsPopOrder(self, pushV, popV):
        # write code here
        stack = []
        while popV:
#如果第一个元素都相同,则直接弹出,压入栈为空还是要比的
#一开始为空,不需要弹出,但是压空了就要比弹出
            if pushV and pushV[0]==popV[0]:
                popV.pop(0)
                pushV.pop(0)
#如果stack最后一个元素与popV第一个元素相同,这就是压完了之后弹出的过程中进行比较。
            elif stack and stack[-1] == popV[0]:
                stack.pop()
                popV.pop(0)
            elif pushV:
                stack.append(pushV.pop(0))
            else:
                return False
        return True
    

从上往下打印二叉树

题目描述

从上往下打印出二叉树的每个节点,同层节点从左至右打印。

解题思路:

广度优先保证从左到右,  层次遍历保证从上到下,广度用队列实现,深度用栈实现,然后左右子树递归。

代码:

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回从上到下每个节点值列表,例:[1,2,3]
    def PrintFromTopToBottom(self, root):
        # write code here
        if not root:
            return []
        queue = []
        result = []
        
        queue.append(root) #找到root,遍历root左右子树
        while len(queue)>0:
            node = queue.pop(0)
            result.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        return result

二叉搜索树的后序遍历序列

题目描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

解题思路:

二叉搜索树又是二叉排序树:

1左子树结点小于根节点,右子树大于根节点

2最后一个元素为根节点,

步骤:
1. 找到根节点
2. 遍历序列,找到第一个大于等于根结点的元素i,则i左侧为左子树、i右侧为右子树;
3. 我们已经知道i左侧所有元素均小于根结点,那么再依次遍历右侧,看是否所有元素均大于根结点;若出现小于根结点的元素,则直接返回false;若右侧全都大于根结点,则:
4. 分别递归判断左/右子序列是否为后序序列;

代码:

# -*- coding:utf-8 -*-
class Solution:
    def VerifySquenceOfBST(self, sequence):
        # write code here
        if not sequence:
            return False
        
        root = sequence[-1]
        
        i=0 
        for node in sequence[:-1]:
            if node > root:
                break
            i+=1
        
        for node in sequence[i:-1]:
            if node < root: #是否右子树都》root
                return False
        
        left = True
        if i>0:
            left = self.VerifySquenceOfBST(sequence[:i])
        #i>0,意味着i=0or1的时候,两个元素没有排序之分,3个元素就有了左右子树之分
        right = True
        #len(sequence)>3 有左右子树之分
        if i < len(sequence)-2 and left:
            right = self.VerifySquenceOfBST(sequence[i+1:])
        return left and right

猜你喜欢

转载自blog.csdn.net/weixin_41813772/article/details/82423962