重建二叉树|用两个栈模拟队列|旋转数组的最小数字

题目一:二叉树

要求:

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

思路:

前序序列能确定根节点,用根节点,把中序划分为左右子树
基于递归的思路,重复上述步骤

class TreeNod:
    def __init__(self,x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def reConstructBinaryTree(self, pre ,tin):                                 # pre是前序,tin是中序列表
        if (len(pre) == 0):
            return None
        root = TreeNode(pre[0])
        tin_root_index = tin.index(root.val)                                   # 在‘中序’中找到根节点,分为左右
        if tin_root_index > 0:                                                 # 有左子树
            new_pre = pre[1:len(pre)+1]                                        # 注意下标志
            new_tin = tin[:tin_root_index]
            root.left = self.reConstructeBinaryTree(new_pre,new_tin)           # 递归进行
        if tin_root_index != len(ten)-1:                                       # 有右子树
            new_tin = [tin_root_index+1:]
            new_pre = [len(pre)-len(new_tin):]
            root.right = self.reConstructBinaryTree(new_pre,new_tin)           # 递归进行
        return root

题目二:栈和队列

要求:

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

思路:

一个栈处理push,新节点放入该栈,一个栈处理pop,初始为空
当需要pop时,如果pop栈不空,则直接出栈,如果空,则从push栈弹出全部内容放到pop栈,pop栈出栈一个

class Solution:
    def __init__(self):
        self.push_stack = []                                                   # 实现队列的push
        seld.pop_stack = []                                                    # 实现队列的pop
    def push(self,node):
        self.push_stack.append(node)
    def pop(self,node):
        if len(self.pop_stack) == 0:
            if len(self.pop_stack) == 0:
                print ('Nothing')
                return None
            else:
                for i in range(len(self.push_stack),-1,-1):
                    self.pop_stack.append(self.push_stack[i])
                self.push_stack = []                                           # 这个时候队列要便是为空,因为pop完了
            value = self.pop_stack[-1]
            self.pop_stack = self.pop_stack[0:-1]
            return value                                                       # 这个value就是我们要pop的

如果用两个队列来模拟栈呢?
初始两个队列都为空
元素a,b,c入栈,则将a,b,c先加入到q1中吧
此时要弹出c,则将ab依次出队,并加入到q2中,将c删除(弹出)
要弹出b,则将a出队,加入到q1中,将b删除
要入栈d,由于q1不空,则追加到q1后面
以此类推

题目三:旋转数组的最小数字

思路:

很简单,从前往后扫,找到第一个比上一个元素小的元素,就说明是最小元素了

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        if len(rotateArray) == 0:
            return 0
        # 这里-1是因为下面代码有i+1
        for i in range(0,len(rotateArray)-1):
            if rotateArray[i+1] < rotateArray[i]:
                return rotateArray[i+1]
        # 都没找到
        return rotateArray[0]

思路2

整个数组由两个递增有序子数组构成。

两个指针分别指向首尾,按照旋转的规则,第一个元素应当大于或者等于最后一个元素(如果小于,说明数组未做旋转,第一个元素就是最小的)。

找mid中间元素,如果mid属于前一半,则它应该大于或等于head,那么此时可以将head移动到mid处,head仍属于前一个数组,目标位于首尾之间;如果mid属于后一半,则它应该小于或等于rear,此时可将rear移动到mid,rear仍属于后一半,目标位于首尾之间。

这种移动方式,head始终属于前一个数组,rear始终属于后一个数组,当hear和rear相邻的时候,说明到达了交界处,rear指向目标。

def minNumberInRotateArray(self, arr):
    if len(rotateArray) == 0:
        return 0
    head = 0
    rear = len(arr) - 1
    if arr[head] < arr[rear]:
        print(arr[head])
    while (head != rear - 1):
        mid = (head + rear)//2
        if arr[mid] >= arr[head]:
            head = mid
            continue
        if arr[mid] <= arr[rear]:
            rear = mid
            continue
    return arr[rear]

参考:https://codingcat.cn/article/22

猜你喜欢

转载自blog.csdn.net/kylin_learn/article/details/88941210