剑指offer的Python实现(五)

21.栈的压入和弹出序列

题目描述

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

# -*- coding:utf-8 -*-

class Solution:

    def IsPopOrder(self, pushV, popV):

        # stack中存入pushV中取出的数据

        stack=[]#辅助栈

        while popV:

            # 如果第一个元素相等,直接都弹出,根本不用压入stack

            if pushV and popV[0]==pushV[0]:

                popV.pop(0)

                pushV.pop(0)

            #如果stack的最后一个元素与popV中第一个元素相等,将两个元素都弹出

            elif stack and stack[-1]==popV[0]:

                stack.pop()

                popV.pop(0)

            # 如果pushV中有数据,压入stack

            elif pushV:

                stack.append(pushV.pop(0))

            # 上面情况都不满足,直接返回false。

            else:

                return False

        return True

 

22.从上往下打印二叉树

题目描述

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

分析:队列的操作,每一次打印一个结点的时候,如果该结点有子结点,则把该结点的子结点放在一个队列的末尾。接下来到队列的头部取出最早进入队列的结点,重复打印操作,直至队列中所有结点都被打印出来为止。

# 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)

        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

 

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

题目描述

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

 

链接:https://www.nowcoder.com/questionTerminal/a861533d45854474ac791d90e447bafd
来源:牛客网

采用分治法的思想,找到根结点、左子树的序列、右子树的序列,分别判断左右子序列是否为二叉树的后序序列。

 

由题意可得:

1. 后序遍历序列的最后一个元素为二叉树的根节点;

2. 二叉搜索树左子树上所有的结点均小于根结点、右子树所有的结点均大于根结点。

 

算法步骤如下:

1. 找到根结点;

2. 遍历序列,找到第一个大于等于根结点的元素i,则i左侧为左子树、i右侧为右子树;

3. 我们已经知道i左侧所有元素均小于根结点,那么再依次遍历右侧,看是否所有元素均大于根结点;若出现小于根结点的元素,则直接返回false;若右侧全都大于根结点,则:

4. 分别递归判断左/右子序列是否为后序序列

 

# -*- coding:utf-8 -*-

class Solution:

    def VerifySquenceOfBST(self, sequence):

        # write code here

        if sequence == None or len(sequence) == 0:

            return False

        length = len(sequence)

        root = sequence[length - 1]

        for i in range(length):

            if sequence[i] > root:

                break

        for j in range(i,length):

            if sequence[j] < root:

                return False

        left = True

        if i >0:

            left = self.VerifySquenceOfBST(sequence[0:i])

        right = True

        if i < length - 1:

            right = self.VerifySquenceOfBST(sequence[i:-1])

        return left and right

 

24.二叉树中和为某一值的路径

题目描述

输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)

思路: 

  • 递归先序遍历树, 把结点加入路径
  • 若该结点是叶子结点则比较当前路径和是否等于期待和。
  • 弹出结点,每一轮递归返回到父结点时,当前路径也应该回退一个结点

# -*- coding:utf-8 -*-

# class TreeNode:

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution:

    # 返回二维列表,内部每个列表表示找到的路径

    def FindPath(self, root, expectNumber):

        # write code here

        if root == None:

            return []

        result = []

       

        def FindPathMain(root,path,currentSum):

            currentSum += root.val

            path.append(root)

           

            isLeaf = root.left ==None and root.right == None

           

            if currentSum == expectNumber and isLeaf:

#黄色显示自己写的有错误的代码,蓝色是相应正确的代码               

onePath.append(path)

                return result.append(onePath)

           

            if currentSum < expectNumber:

                FindPathMain(root.left,path,currentSum)

                FindPathMain(root.right,path,currentSum)

               onePath = []

                for node in path:

                    onePath.append(node.val)

                result.append(onePath)

           

            if currentSum < expectNumber:

                if root.left:

                    FindPathMain(root.left,path,currentSum)

                if root.right:

                    FindPathMain(root.right,path,currentSum)

            path.pop()

           

        FindPathMain(root,[],0)

        return result

 

25.复杂链表的复制

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

https://i-blog.csdnimg.cn/blog_migrate/bd165fb21c48ffef09ba929cc2a515b9.png

 

# -*- coding:utf-8 -*-

# class RandomListNode:

#     def __init__(self, x):

#         self.label = x

#         self.next = None

#         self.random = None

class Solution:

    # 返回 RandomListNode

    def Clone(self, pHead):

        # write code here

        if not pHead:

            return None

        #在原链上复制链,在每个节点后插入一个复制节点

        tmp = pHead

        while tmp:

            ntmp = RandomListNode(tmp.label)#定义一个新结点,之前的树是仅仅取出结点的值放在列表里

            ntmp.next = tmp.next

            tmp.next = ntmp

            tmp = ntmp.next

        #遍历合成链,复制random关系

        tmp = pHead

        while tmp:

            tmp.next.random = tmp.random.next if tmp.random else None

            tmp = tmp.next.next

        #拆链

        tmp,ntmp = pHead,pHead.next

        newHead = pHead.next

        while tmp:

            tmp.next = ntmp.next

            tmp = tmp.next先把ntmp的下一个结点赋值给tmp的下一个结点,然后把这个新的(tmp的下一个结点)赋值给tmp,实现奇数那个拆解。

            if not tmp:

                break

            ntmp.next = tmp.next

            ntmp = ntmp.next

        return newHead

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值