Maisie leetcode笔记1

花花酱blog:


花花酱 LeetCode Problem List 题目列表 – Huahua’s Tech Roadhttps://zxi.mytechroad.com/blog/leetcode-problem-categories/

Depth First Traversals: 

(a) Inorder (Left, Root, Right) 中序:左中右

(b) Preorder (Root, Left, Right) 前序:中左右

(c) Postorder (Left, Right, Root) 后序:左右中

Breadth-First or Level Order Traversal 层序遍历BFS

94.Binary Tree Inorder Traversal 

recursive way:

首先python的代码, function前面要加def,在call function的时候要加self.

在function里面没有标点符号。在function的parameter里面写上self

在recursive里面,我们用一个Helper function来循环

def inorderTraversal(self, root):
        res = []
        self.helper(root, res)
        return res
    
def helper(self, root, res):
    if root:
        self.helper(root.left, res)
        res.append(root.val)
        self.helper(root.right, res)

If binary: O(log n)

If skewed: O(n)

iteratively:

def inorderTraversal(self, root):
        res = []
        stack = []
        current = root
        while True:
            while current:
                stack.append(current)
                current = current.left
            if not stack:
                return res
            current = stack.pop()
            res.append(current.val)
            current = current.right
def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        stack = []
        res = []
        if not root:
            return None
        while root or stack:
            while root:
                stack.append(root)
                root = root.left
            root = stack.pop()
            res.append(root.val)
            root = root.right
        return res

iterative的从root开始,先把root 放进stack,让current指到current.left,

然后把所有的current.left都放到stack里。一直到没有left.

查到3,没有left了,把3 pop出去,让res接收3

然后查3的right, 3 没有right,所以current = 下一个pop的,等于2

把2放进res里。然后查2的right->4.

4被放入stack,然后查4的左边,然后Pop4,再查4的右边,没有,则pop 1。

二叉树后序遍历两遍图解

力扣https://leetcode.cn/problems/n-ary-tree-postorder-traversal/solution/python-die-dai-fa-by-user3935a/

力扣https://leetcode.cn/problems/n-ary-tree-preorder-traversal/solution/yi-tao-quan-fa-shua-diao-nge-bian-li-shu-de-wen--3/

226 翻转二叉树


def invertTree(self, root: TreeNode) -> TreeNode:
      
       self.traverse(root)
    //return root 就可以
       return root
   //过一遍每一个node
   def traverse(self, root):
      //这是base case
       if not root:
           return None
      //让两个node相交换
      //无所谓是前中后(不是有了子节点才能算出来的,到了这个点就交换两个下面的node也可以)
       //用前置
       root.left, root.right = root.right, root.left
       self.traverse(root.left)
       self.traverse(root.right)

用dynamic programing的想法做:

先是把大的problem分成小的problem

在任意一个点上,让左子树的左右翻转,让右子树的左右翻转,然后再翻转左子树和右子树

左子树翻转完之后必须要等于一个值(应该是左子树的root)

右子树翻转完之后必须要等于一个值(应该是右子树的root)

然后交换两个值就可以实现左右子树的翻转

def invertTree(self, root: TreeNode) -> TreeNode:
       if not root:
           return None
       left = self.invertTree(root.left)
       right = self.invertTree(root.right)
 
       root.right = left
       root.left = right
       return root
 

 116. 填充每个节点的下一个右侧节点指针

因为原本没有point to any thing 就是point to NULL,所以我们不需要一开始把所有node point to null

def connect(self, root):
       """
       :type root: Node
       :rtype: Node
       """
       if not root:
           return None
       node1 = root.left
       node2 = root.right
       self.traverse(node1, node2)
       return root
 
   def traverse(self, node1, node2):
       if not node1 or not node2:
           return None
       /**** 前序位置 ****/

       // 将传入的两个节点穿起来
       node1.next = node2
       // 连接相同父节点的两个子节点
       self.traverse(node1.left, node1.right)
       self.traverse(node2.left, node2.right)
       // 连接跨越父节点的两个子节点
       self.traverse(node1.right, node2.left)

114. 二叉树展开为链表 


def flatten(self, root):
       """
       :type root: TreeNode
       :rtype: None Do not return anything, modify root in-place instead.
       """
       #base case
       if not root:
           return None
      
       #左子树展平
       self.flatten(root.left)
       #右子树展平
       self.flatten(root.right)
       
       if root.left:
            #p是指向左子树root的指针
            p = root.left
            #当p有右节点时,一直向右
            while p.right:
                p = p.right
            #把右子树接到左子树最右边的节点上
            p.right = root.right
            #左子树为空,原先的左子树赋值成为右子树
            temp = root.left
            root.left = None
            root.right = temp
        return root 

递归的终极思想是:相信函数定义,跳出函数本身

二叉树解题的思维模式分两类:

1、是否可以通过遍历一遍二叉树得到答案?如果可以,用一个 traverse 函数配合外部变量来实现,这叫「遍历」的思维模式。

2、是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案?如果可以,写出这个递归函数的定义,并充分利用这个函数的返回值,这叫「分解问题」的思维模式。

无论使用哪种思维模式,你都需要思考:

如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序位置)做?其他的节点不用你操心,递归函数会帮你在所有节点上执行相同的操作。

 105. Construct Binary Tree from Preorder and Inorder Traversal


def buildTree(self, preorder, inorder):
        
        return self.building(preorder,0, len(preorder)-1,inorder,0,len(preorder)-1)

def building(self,preorder,prestart, preend,inorder,instart,inend):
        //base case
        if (prestart > preend):
                return None
        target = preorder[prestart]
        //找到inorder 里的root
        for i in range(len(inorder)):
            if inorder[i] == target:
                index = i

        # 先构造当前的根节点
        root = TreeNode(target)

        root.left = self.building(preorder,prestart+1, 
prestart + index-instart, inorder,instart,index-1)
        root.right = self.building(preorder,
prestart+index-instart+1, preend, inorder,index+1,inend)
        return root

106. 从中序与后序遍历序列构造二叉树

 

def buildTree(self, inorder, postorder):
        """
        :type inorder: List[int]
        :type postorder: List[int]
        :rtype: TreeNode
        """
        #为了找到Index,构建helper function和left and right pointers
        #左闭右闭
        def dfs(inorder,left,right,postorder,start,end):
            #base case
            if left > right:
                return None
            #在后序中找到root,最后一个就是root
            target = postorder[end]
            #在中序中找root的index
            for i in range(len(inorder)):
                #如果值和root的值相等
                if inorder[i] == target:
                    index = i
                
            root = TreeNode(target)
            #他的size不用加1
            leftSize = index-left
            root.left = dfs(inorder,left,index-1,postorder,start, start+leftSize-1)
            root.right = dfs(inorder,index+1,right,postorder,start+leftSize,end-1)
            return root
        n=len(inorder)-1
        return dfs(inorder,0,n,postorder,0,n)

时间复杂度:O(N^2) 因为每次递归都在当前长度上减少了一个根节点,所以需要N次,每次索引中序遍历数组为O(N),所以为平方级别复杂度

 100. 相同的树(分治法)

def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
        ###递归输出条件,有一个空另外一个非空则False
        if p is None and q is not None: 
            return False
        ###递归输出条件,有一个空另外一个非空则False
        if p is not None and q is None: 
            return False
        ###递归输出条件,均为空则True
        if p is None and q is None:
            return True
        #判断条件,值是否相等
        if p.val != q.val:
            return False
        #递归为左树与右树是否相等
        return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)

在Python里面,用elif,True和False首字母大写

分治法如果不能得到最终结果,循环的地方加return试一试

这题不能用简单的遍历,因为把null去掉了无法看出左边的树是否等于右边

102. Binary Tree Level Order Traversal

层序遍历的时候一定要使用BFS模版

BFS使用的时候通常与queue一起

首先要queue = collections.deque()

BFS模板


BFS的模版(如果不需
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值