牛客经典101题题解集--二叉树

目录

二叉树

二叉树的前序遍历

题目

代码

java

python

二叉树的中序遍历

题目

代码

java

python

二叉树的后序遍历

题目

代码

java

python

求二叉树的层序遍历

题目

分析

代码

java

python

按之字形顺序打印二叉树

题目

分析

代码

java

python

二叉树的最大深度

题目

分析

代码

java

python

二叉树中和为某一值的路径(一)

题目

代码

java

python

二叉搜索树与双向搜索链表

题目

思路

代码

java

python

对称的二叉树

题目

分析

代码

java

python

合并二叉树

题目

分析

代码

java

python

二叉树的镜像

题目

代码

java

python

判断是不是二叉搜索树

题目

分析

代码

java

python

判断是不是完全二叉树

题目

分析

代码

java

python

判断是不是平衡二叉树

题目

分析

代码

java

python

二叉搜索树的最近公共祖先

题目

分析

代码

java

python

在二叉树中找到两个节点的最近公共祖先

题目

分析

代码

java

python

序列化二叉树

题目

分析

代码

java

python

重建二叉树

题目

分析

代码

java

python

输出二叉树的右视图

题目

分析

代码

java

python

总结


二叉树

二叉树的前序遍历

题目

给你二叉树的根节点 root ,返回它节点值的 前序遍历。

数据范围:二叉树的节点数量满足 1≤𝑛≤100 1≤n≤100 ,二叉树节点的值满足 1≤𝑣𝑎𝑙≤100 1≤val≤100 ,树的各节点的值各不相同

示例 1:

示例1

输入:{1,#,2,3}

返回值:[1,2,3]

代码

java
javascript 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型一维数组
     */
     List<Integer> list=new ArrayList<>();
    public int[] preorderTraversal (TreeNode root) {
        // write code here
        if(root==null){
            return new int[0];
        }
        dfs(root);
        int [] res=new int[list.size()];
        for(int i=0;i<list.size();i++){
            res[i]=list.get(i);
        }
        return res;

    }
    public void dfs(TreeNode root){
        if(root==null){
            return;
        }
        list.add(root.val);
        dfs(root.left);
        dfs(root.right);
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型一维数组
#
class Solution:
    list1=[]
    def preorderTraversal(self , root: TreeNode) -> List[int]:
        
        self.dfs(root)
        return self.list1
        # write code here
    def dfs(self,root: TreeNode):
        if not root:
            return
        self.list1.append(root.val)
        self.dfs(root.left)
        self.dfs(root.right)

二叉树的中序遍历

题目

就是中序遍历,不写了

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型一维数组
     */
     List<Integer> result=new ArrayList<>();
    public int[] inorderTraversal (TreeNode root) {
        // write code here
        dfs(root);
        int [] res=new int[result.size()];
        for(int i=0;i<result.size();i++){
            res[i]=result.get(i);
        }
        return res;

    }
    public void dfs(TreeNode root){
        if(root==null){
            return;
        }
        dfs(root.left);
        result.add(root.val);
        dfs(root.right);
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型一维数组
#
class Solution:
    list1=[]
    def inorderTraversal(self , root: TreeNode) -> List[int]:
        # write code here
        self.dfs(root)
        return self.list1
        # write code here
    def dfs(self,root: TreeNode):
        if not root:
            return
        
        self.dfs(root.left)
        self.list1.append(root.val)
        self.dfs(root.right)

二叉树的后序遍历

题目

一样

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型一维数组
     */
     List<Integer> result=new ArrayList<>();
    public int[] postorderTraversal (TreeNode root) {
        // write code here
        dfs(root);
        int [] res=new int[result.size()];
        for(int i=0;i<result.size();i++){
            res[i]=result.get(i);
        }
        return res;
    }
    public void dfs(TreeNode root){
        if(root==null){
            return;
        }
        dfs(root.left);
        dfs(root.right);
        result.add(root.val);
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型一维数组
#
class Solution:
    list1=[]
    def postorderTraversal(self , root: TreeNode) -> List[int]:
        # write code here
        # write code here
        self.dfs(root)
        return self.list1
        # write code here
    def dfs(self,root: TreeNode):
        if not root:
            return
        
        self.dfs(root.left)
        
        self.dfs(root.right)
        self.list1.append(root.val)

求二叉树的层序遍历

题目

给定一个二叉树,返回该二叉树层序遍历的结果,(从左到右,一层一层地遍历)

例如:

给定的二叉树是{3,9,20,#,#,15,7},

该二叉树层序遍历的结果是

\[3\], \[9,20\], \[15,7

]

提示:

0 <= 二叉树的结点数 <= 1500

示例1

输入:{1,2}

返回值:[[1],[2]]

示例2

输入:{1,2,3,4,#,#,5}

返回值:[[1],[2,3],[4,5]]

分析

创建一个队列就行

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型ArrayList<ArrayList<>>
     */
    public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        // write code here
            Queue<TreeNode> que=new LinkedList<>();
            ArrayList<ArrayList<Integer>> res=new ArrayList<>();
            if(root==null){
                return res;
            }
            que.offer(root);
            while(!que.isEmpty()){
                ArrayList<Integer> re=new ArrayList<>();
                int size=que.size();
                while(size>0){
                    TreeNode temp=que.poll();
                    re.add(temp.val);
                    if(temp.left!=null){
                        que.offer(temp.left);
                    }
                    if(temp.right!=null){
                        que.offer(temp.right);
                    }
                    size-=1;
                }
                 res.add(re);
            }
            return res;
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型二维数组
#
import collections
class Solution:
    def levelOrder(self , root: TreeNode) -> List[List[int]]:
        # write code here
        if not root:
            return []
        que=collections.deque([root])
        result=[]
        while que:
            level=[]
            size=len(que)
            while size>0:
                temp=que.popleft()
                level.append(temp.val)
                if temp.left:
                    que.append(temp.left)
                if temp.right:
                    que.append(temp.right)
                size-=1
            result.append(level)
        return result

按之字形顺序打印二叉树

题目

给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)

数据范围:0≤𝑛≤1500,树上每个节点的val满足 ∣𝑣𝑎𝑙∣<=1500

要求:空间复杂度:𝑂(𝑛),时间复杂度:𝑂(𝑛)

例如:

给定的二叉树是{1,2,3,#,#,4,5}

该二叉树之字形层序遍历的结果是

\[1\], \[3,2\], \[4,5

]

示例1

输入:{1,2,3,#,#,4,5}

返回值:[[1],[3,2],[4,5]]

复制说明:如题面解释,第一层是根节点,从左到右打印结果,第二层从右到左,第三层从左到右。

示例2

输入:{8,6,10,5,7,9,11}

返回值:[[8],[10,6],[5,7,9,11]]

示例3

输入:{1,2,3,4,5}

返回值:[[1],[3,2],[4,5]]

分析

本质上还是层序遍历,只不过偶数层要反转一下,所以定义一个布尔类型的变量即可

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pRoot TreeNode类 
     * @return int整型ArrayList<ArrayList<>>
     */
     
    public ArrayList<ArrayList<Integer>> Print (TreeNode pRoot) {
        // write code here
        Queue<TreeNode> que=new LinkedList<>();
        ArrayList<ArrayList<Integer>> res=new ArrayList<>();
        if(pRoot==null){
            return res;
        }
        que.offer(pRoot);
        boolean flag=false;
        while(!que.isEmpty()){
            int size=que.size();
            ArrayList<Integer> re=new ArrayList<>();
            while(size-->0){
                TreeNode temp=que.poll();
                re.add(temp.val);
                if(temp.left!=null){
                    que.offer(temp.left);
                }
                if(temp.right!=null){
                    que.offer(temp.right);
                }

            }
            if(flag){
                    Collections.reverse(re);
                }
                flag=!flag;
                res.add(re);
        }
        return res;
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param pRoot TreeNode类 
# @return int整型二维数组
#
import collections
class Solution:
    def Print(self , pRoot: TreeNode) -> List[List[int]]:
        # write code here
        if not pRoot:
            
            return []
        flag=False
        que=collections.deque([pRoot])
        result=[]
        while que:
            level=[]
            size=len(que)
            while size>0:
                temp=que.popleft()
                level.append(temp.val)
                if temp.left:
                    que.append(temp.left)
                if temp.right:
                    que.append(temp.right)
                size-=1
            if flag:
                level=level[::-1]
            flag=not flag
            result.append(level)
        return result

二叉树的最大深度

题目

求给定二叉树的最大深度,

深度是指树的根节点到任一叶子节点路径上节点的数量。

最大深度是所有叶子节点的深度的最大值。

(注:叶子节点是指没有子节点的节点。)

数据范围:0≤𝑛≤100000,树上每个节点的val满足 ∣𝑣𝑎𝑙∣≤100

要求: 空间复杂度 𝑂(1),时间复杂度 𝑂(𝑛)

分析

递归

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        // write code here
        if(root==null){
            return 0;
        }
        int left=maxDepth(root.left);
        int right=maxDepth(root.right);
        return Math.max(left,right)+1;

    }

}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型
#
class Solution:
    def maxDepth(self , root: TreeNode) -> int:
        # write code here
        if not root:
            return 0

        a=self.maxDepth(root.left)
        b=self.maxDepth(root.right)
        return max(a,b)+1

二叉树中和为某一值的路径(一)

题目

给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。

1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点

2.叶子节点是指没有子节点的节点

3.路径只能从父节点到子节点,不能从子节点到父节点

4.总节点数目为n

例如:

给出如下的二叉树, 𝑠𝑢𝑚=22 sum=22,

返回true,因为存在一条路径 5→4→11→25→4→11→2的节点值之和为 22

数据范围:

1.树上的节点数满足 0≤𝑛≤10000

2.每 个节点的值都满足 ∣𝑣𝑎𝑙∣≤1000

要求:空间复杂度 𝑂(𝑛),时间复杂度 𝑂(𝑛)

进阶:空间复杂度 𝑂(树的高度),时间复杂度 𝑂(𝑛)

示例1

输入:{5,4,8,1,11,#,9,#,#,2,7},22

返回值:true

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @param sum int整型 
     * @return bool布尔型
     */
    public boolean hasPathSum (TreeNode root, int sum) {
        // write code here
        if(root==null){
            return false;
        }
        sum-=root.val;
        if(root.left==null && root.right==null){
            return sum==0;
        }
        if(root.left!=null){
            boolean left=hasPathSum(root.left,sum);
            if(left){
                return true;
            }
        }
       if(root.right!=null){
            boolean right=hasPathSum(root.right,sum);
            if(right){
                return true;
            }
        }
        return false;

    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @param sum int整型 
# @return bool布尔型
#
class Solution:
    def hasPathSum(self , root: TreeNode, sum: int) -> bool:
        # write code here
        if not root:
            return False
        sum-=root.val
        if not root.left and not root.right:
            return sum==0
        if root.left:
            left=self.hasPathSum(root.left,sum)
            if left:
                return True
        if root.right:
            right=self.hasPathSum(root.right,sum)
            if right:
                return True
        return False

二叉搜索树与双向搜索链表

题目

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示

数据范围:输入二叉树的节点数 0≤𝑛≤10000≤n≤1000,二叉树中每个节点的值 0≤𝑣𝑎𝑙≤10000≤val≤1000

要求:空间复杂度𝑂(1)O(1)(即在原树上操作),时间复杂度 𝑂(𝑛)O(n)

注意:

1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继

2.返回链表中的第一个节点的指针

3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构

4.你不用输出双向链表,程序会根据你的返回值自动打印输出

输入描述:

二叉树的根节点

返回值描述:

双向链表的其中一个头节点。

示例1

输入:{10,6,14,4,8,12,16}

复制返回值:From left to right are:4,6,8,10,12,14,16;From right to left are:16,14,12,10,8,6,4;

复制说明:输入题面图中二叉树,输出的时候将双向链表的头节点返回即可。

示例2

输入:{5,4,#,3,#,2,#,1}

复制返回值:From left to right are:1,2,3,4,5;From right to left are:5,4,3,2,1;

复制说明:

复制代码
                    5
                  /
                4
              /
            3
          /
        2
      /
    1
树的形状如上图       

思路

首先一个信息是他是二叉搜索树,所以左子树都比当前根节点小,右子树都比当前根节点大。所以我们利用栈,一直向左下方走去,直到变成null为止,把他加入栈,然后再弹出。这里我们需要区分第一个节点与其他节点。第一个节点他后一个和前一个都指向他自身。所以这里定义一个布尔类型的变量。当进行完这些操作以后,让当前指针指向它的右节点,继续循环。

代码

java
java 复制代码
import java.util.*;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null){
            return null;
        }
        Stack<TreeNode> stack=new Stack<TreeNode>();
        TreeNode p=pRootOfTree;
        TreeNode pre=null;
        boolean flag=true;
        while(p!=null || !stack.isEmpty()) {
            while(p!=null){
            stack.push(p);
            p=p.left;
            }                 
        p=stack.pop();
        if(flag){
            pRootOfTree=p;
            pre=pRootOfTree;
            flag=false;
        }else{
            pre.right=p;
            p.left=pre;
            pre=p;
        }
        p=p.right;
         }
        return pRootOfTree;    
    }
    
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

#
# 
# @param pRootOfTree TreeNode类 
# @return TreeNode类
#
class Solution:
    def Convert(self , pRootOfTree ):
        # write code here
        if not  pRootOfTree:
            return None
        p=pRootOfTree
        pre=None
        stack=[]
        flag=True
        while(p or stack):
            while p:
                stack.append(p)
                p=p.left
            p = stack.pop()
            if flag:
                pRootOfTree=p
                pre=pRootOfTree
                flag=False
            else:
                pre.right=p
                p.left=pre
                pre=p
            p=p.right
        return pRootOfTree

对称的二叉树

题目

给定一棵二叉树,判断其是否是自身的镜像(即:是否对称)

例如:下面这棵二叉树是对称的

下面这棵二叉树不对称。

数据范围:节点数满足 0≤𝑛≤1000,节点上的值满足 ∣𝑣𝑎𝑙∣≤1000

要求:空间复杂度O(n),时间复杂度 𝑂(𝑛)

备注:

你可以用递归和迭代两种方法解决这个问题

示例1

输入:{1,2,2,3,4,4,3}

返回值:true

示例2

输入:{8,6,9,5,7,7,5}

返回值:false

分析

返回false的几种情况:

一个为null一个不为null

两个节点的值不相等。

返回true的情况是:

两个都为null

两个节点的值相等

我们在比较的时候,注意是root的左孩子和root2的右孩子比,

root的右孩子和root2的左孩子比

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pRoot TreeNode类 
     * @return bool布尔型
     */
    public boolean isSymmetrical (TreeNode pRoot) {
        // write code here
        if(pRoot==null){
            return true;
        }
        return compare(pRoot.left,pRoot.right);
    }
    public boolean compare(TreeNode root,TreeNode root2){
        if(root==null && root2==null){
            return true;
        }
        if(root!=null && root2==null){
            return false;
        }
        if(root==null && root2!=null){
            return false;
        }
        if(root.val!=root2.val){
            return false;
        }
        boolean inside=compare(root.right,root2.left);
        boolean outside=compare(root.left,root2.right);
        return inside && outside;
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param pRoot TreeNode类 
# @return bool布尔型
#
class Solution:
    def isSymmetrical(self , pRoot: TreeNode) -> bool:
        # write code here
        if not pRoot:
            return True
        return self.compare(pRoot.left,pRoot.right)
    def compare(self,r1:TreeNode ,r2:TreeNode) ->bool:
        if not r1 and not r2:
            return True
        if not r1 and r2:
            return False
        if r1 and not r2:
            return False
        if r1.val!=r2.val:
            return False
        inside=self.compare(r1.left,r2.right)
        outside=self.compare(r1.right,r2.left)
        return inside and outside

合并二叉树

题目

已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。例如:

两颗二叉树是:

Tree 1

Tree 2

合并后的树为

数据范围:树上节点数量满足 0≤𝑛≤500,树上节点的值一定在32位整型范围内。

进阶:空间复杂度 𝑂(1) ,时间复杂度 𝑂(𝑛)

示例1

输入:{1,3,2,5},{2,1,3,#,4,#,7}

返回值:{3,4,5,5,4,#,7}

说明:如题面图

示例2

输入:{1},{}

返回值:{1}

分析

这道题和上面对称二叉树差不多。

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param t1 TreeNode类 
     * @param t2 TreeNode类 
     * @return TreeNode类
     */
    public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
        // write code here
        return merge(t1,t2);
    }
    public TreeNode merge(TreeNode t1,TreeNode t2){
        if(t1==null && t2==null){
            return t1;
        }
        if(t1==null && t2!=null){
            return t2;
        }
        if(t1!=null && t2==null){
            return t1;
        }
       int sum=t1.val+t2.val;
       TreeNode p=new TreeNode(sum);
       p.left=merge(t1.left,t2.left);
       p.right=merge(t1.right,t2.right);
       return p;
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param t1 TreeNode类 
# @param t2 TreeNode类 
# @return TreeNode类
#
class Solution:
    def mergeTrees(self , t1: TreeNode, t2: TreeNode) -> TreeNode:
        return self.merge(t1,t2)
        # write code here
    def merge(self,t1: TreeNode, t2: TreeNode) -> TreeNode:
        if not t1 and not t2:
            return None
        if not t1 and t2:
            return t2
        if t1 and not t2:
            return t1
        num=t1.val+t2.val
        node=TreeNode(num)
        node.left=self.merge(t1.left,t2.left)
        node.right=self.merge(t1.right,t2.right)
        return node

二叉树的镜像

题目

操作给定的二叉树,将其变换为源二叉树的镜像。

数据范围:二叉树的节点数 0≤𝑛≤10000≤n≤1000 , 二叉树每个节点的值 0≤𝑣𝑎𝑙≤10000≤val≤1000

要求: 空间复杂度 𝑂(𝑛)O(n) 。本题也有原地操作,即空间复杂度 𝑂(1)O(1) 的解法,时间复杂度 𝑂(𝑛)O(n)

比如:

源二叉树

镜像二叉树

示例1

输入:{8,6,10,5,7,9,11}

返回值:{8,10,6,11,9,7,5}

说明:如题面所示

示例2

输入:{}

返回值:{}

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pRoot TreeNode类 
     * @return TreeNode类
     */
    public TreeNode Mirror (TreeNode pRoot) {
        // write code here
        if(pRoot==null){
            return null;
        }
        Mirror(pRoot.left);
        Mirror(pRoot.right);
        m(pRoot);
        return pRoot;
    }
    public TreeNode m(TreeNode p){
        if(p.left==null && p.right==null){
            return null;
        }
        TreeNode temp=p.left;
        p.left=p.right;
        p.right=temp;
        return p;
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param pRoot TreeNode类 
# @return TreeNode类
#
class Solution:
    def Mirror(self , pRoot: TreeNode) -> TreeNode:
        # write code here
        if not pRoot:
            return None
        self.Mirror(pRoot.left)
        self.Mirror(pRoot.right)
        self.reverse(pRoot)
        return pRoot
        

    def reverse(self , pRoot: TreeNode):
        temp=pRoot.left
        pRoot.left=pRoot.right
        pRoot.right=temp
        

判断是不是二叉搜索树

题目

给定一个二叉树根节点,请你判断这棵树是不是二叉搜索树。

二叉搜索树满足每个节点的左子树上的所有节点均小于当前节点且右子树上的所有节点均大于当前节点。

例:

图1

图2

数据范围:节点数量满足 1≤𝑛≤104 1≤n≤104 ,节点上的值满足 −231≤𝑣𝑎𝑙≤231−1

示例1

输入:{1,2,3}

返回值:false

说明:如题面图1

示例2

输入:{2,1,3}

返回值:true

说明:如题面图2

分析

把握好二叉搜索树的特点:

中序遍历得到的是有序数组。

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
     ArrayList<Integer> re=new ArrayList<>();
    public boolean isValidBST (TreeNode root) {
        // write code here
        dfs(root);
        for(int i=1;i<re.size();i++){
            if(re.get(i-1)>=re.get(i)){
                return false;
            }
        }
        return true;
    }
    public void dfs(TreeNode root){
        if(root==null){
            return ;
        }
        dfs(root.left);
        re.add(root.val);
        dfs(root.right);
        
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return bool布尔型
#
class Solution:
    list=[]
    def isValidBST(self , root: TreeNode) -> bool:
        # write code here
        self.dfs(root)
        for i in range(1,len(self.list)):
            if self.list[i-1]>=self.list[i]:
                return False
        return True
    def dfs(self , root: TreeNode):
        if not root:
            return 
        self.dfs(root.left)
        self.list.append(root.val)
        self.dfs(root.right)

判断是不是完全二叉树

题目

给定一个二叉树,确定他是否是一个完全二叉树。

完全二叉树的定义:若二叉树的深度为 h,除第 h 层外,其它各层的结点数都达到最大个数,第 h 层所有的叶子结点都连续集中在最左边,这就是完全二叉树。(第 h 层可能包含 [1~2h] 个节点)

数据范围:节点数满足 1≤𝑛≤100

样例图1:

样例图2:

样例图3:

示例1

输入:{1,2,3,4,5,6}

返回值:true

示例2

输入:{1,2,3,4,5,6,7}

返回值:true

分析

这里使用flag来记录当前节点是否为空,如果当前节点为空的话那么设置为false,再循环,如果后面的节点不为空了,那就说明不是完全二叉树,要返回false。不能是空就返回false

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
    public boolean isCompleteTree (TreeNode root) {
        // write code here
        if(root==null){
            return true;
        }
        boolean flag=false;
        Deque<TreeNode> que=new LinkedList<>();
        que.offer(root);
        while(!que.isEmpty()){
            TreeNode temp=que.pop();
            if(temp==null){
                flag=true;
            }else{
                if(flag){
                    return false;
                }
                que.offer(temp.left);
                que.offer(temp.right);
            }
        }
    return true;
    }
}
python
python 复制代码
import collections
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return bool布尔型
#
class Solution:
    def isCompleteTree(self , root: TreeNode) -> bool:
        # write code here
        flag=False
        if not root:
            return True
        que=collections.deque([root])
        while que:
            temp=que.popleft()
            if not temp:
                flag=True
            else:
                if flag:
                    return False
                que.append(temp.left)
                que.append(temp.right)
        return True    

判断是不是平衡二叉树

题目

输入一棵节点数为 n 二叉树,判断该二叉树是否是平衡二叉树。

在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树

平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

样例解释:

样例二叉树如图,为一颗平衡二叉树

注:我们约定空树是平衡二叉树。

数据范围:𝑛≤100,树上节点的val值满足 0≤𝑛≤1000

要求:空间复杂度𝑂(1),时间复杂度 𝑂(𝑛)

输入描述:

输入一棵二叉树的根节点

返回值描述:

输出一个布尔类型的值

示例1

输入:{1,2,3,4,5,6,7}

返回值:true

示例2

输入:{}

返回值:true

分析

用-1来代表不满足,也就是左子树和右子树的高度差大于1,所以在递归继续的时候,只要左右子树他们的高度差大于1,那么一定不满足条件,就返回-1.如果当前分支满足条件,就返回当前分支左右子树的最大高度,以便于继续递归判断。

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pRoot TreeNode类 
     * @return bool布尔型
     */
    public boolean IsBalanced_Solution (TreeNode pRoot) {
        // write code here
        if(pRoot==null){
            return true;
        }
        return dfs(pRoot)>-1;
    }
    public int dfs(TreeNode root){
        if(root==null){
            return 0;
        }
        int left=dfs(root.left);
        int right=dfs(root.right);
        if(left==-1){
            return -1;
        }
        if(right==-1){
            return -1;
        }
        if(Math.abs(left-right)>1){
            return -1;
        }
        return Math.max(left,right)+1;
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param pRoot TreeNode类 
# @return bool布尔型
#
class Solution:
    def IsBalanced_Solution(self , pRoot: TreeNode) -> bool:
        # write code here
        if not pRoot:
            return True
        return self.dfs(pRoot)>-1
    def dfs(self,root) -> int:
        if not root:
            return 0
        left=self.dfs(root.left)
        right=self.dfs(root.right)
        if left==-1:
            return -1
        if right==-1:
            return -1
        if abs(left-right)>1:
            return -1
        return max(left,right)+1

二叉搜索树的最近公共祖先

题目

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

1.对于该题的最近的公共祖先定义:对于有根树T的两个节点p、q,最近公共祖先LCA(T,p,q)表示一个节点x,满足x是p和q的祖先且x的深度尽可能大。在这里,一个节点也可以是它自己的祖先.

2.二叉搜索树是若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值

3.所有节点的值都是唯一的。

4.p、q 为不同节点且均存在于给定的二叉搜索树中。

数据范围:

3<=节点总数<=10000

0<=节点值<=10000

如果给定以下搜索二叉树: {7,1,12,0,4,11,14,#,#,3,5},如下图:

示例1

输入:{7,1,12,0,4,11,14,#,#,3,5},1,12

返回值:7

说明:节点1 和 节点12的最近公共祖先是7

示例2

输入:{7,1,12,0,4,11,14,#,#,3,5},12,11

返回值:12

说明:因为一个节点也可以是它自己的祖先.所以输出12

分析

抓住二叉搜索树的特点,当前节点的左子树都比当前节点小,当前节点的右子树都比当前节点大

如果两个节点都比当前节点小,那么就去当前节点的左子树找,如果两个都比当前节点大,那么就去当前节点的右子树找,如果一个大一个小,那么答案就是当前节点;如果一个等于,一个大于或小于,那么答案也是当前节点

善用递归,想明白几种情况

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @param p int整型 
     * @param q int整型 
     * @return int整型
     */
    public int lowestCommonAncestor (TreeNode root, int p, int q) {
        // write code here
        if(p>root.val && q>root.val){
            return lowestCommonAncestor(root.right,p,q);
        }
        if(p<root.val && q<root.val){
            return lowestCommonAncestor(root.left,p,q);
        }
        return root.val;
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @param p int整型 
# @param q int整型 
# @return int整型
#
class Solution:
    def lowestCommonAncestor(self , root: TreeNode, p: int, q: int) -> int:
        # write code here
        if p<root.val and q<root.val:
            return self.lowestCommonAncestor(root.left,p,q)
        if p>root.val and q>root.val:
            return self.lowestCommonAncestor(root.right,p,q)
        return root.val

在二叉树中找到两个节点的最近公共祖先

题目

给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。

数据范围:树上节点数满足 1≤𝑛≤105 1≤n≤105 , 节点值val满足区间 [0,n)

要求:时间复杂度 𝑂(𝑛)

注:本题保证二叉树中每个节点的val值均不相同。

如当输入{3,5,1,6,2,0,8,#,#,7,4},5,1时,二叉树{3,5,1,6,2,0,8,#,#,7,4}如下图所示:

所以节点值为5和节点值为1的节点的最近公共祖先节点的节点值为3,所以对应的输出为3。

节点本身可以视为自己的祖先

示例1

输入:{3,5,1,6,2,0,8,#,#,7,4},5,1

返回值:3

示例2

输入:{3,5,1,6,2,0,8,#,#,7,4},2,7

返回值:2

分析

这道题在上一题的基础上变成了普通的二叉树,不是搜索树。

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
    public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
        // write code here
        if(root==null){
            return -1;
        }
        if(root.val==o1 || root.val==o2){
            return root.val;
        }
        int left=lowestCommonAncestor(root.left,o1,o2);
        int right=lowestCommonAncestor(root.right,o1,o2);
        
        if(left!=-1 && right!=-1){
            return root.val;
        }
        return left!=-1 ? left:right;
    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @param o1 int整型 
# @param o2 int整型 
# @return int整型
#
class Solution:
    def lowestCommonAncestor(self , root: TreeNode, o1: int, o2: int) -> int:
        # write code here
        if not root:
            return -1
        if root.val==o1 or root.val==o2:
            return root.val
        left=self.lowestCommonAncestor(root.left,o1,o2)
        right=self.lowestCommonAncestor(root.right,o1,o2)
        if left!=-1 and right!=-1:
            return root.val
        elif left!=-1:
            return left
        else:
            return right

序列化二叉树

题目

请实现两个函数,分别用来序列化和反序列化二叉树,不对序列化之后的字符串进行约束,但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。

二叉树的序列化(Serialize)是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树等遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#)

二叉树的反序列化(Deserialize)是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

例如,可以根据层序遍历的方案序列化,如下图:

层序序列化(即用函数Serialize转化)如上的二叉树转为"{1,2,3,#,#,6,7}",再能够调用反序列化(Deserialize)将"{1,2,3,#,#,6,7}"构造成如上的二叉树。

再举一个例子

层序序列化(即用函数Serialize转化)如上的二叉树转为"{5,4,#,3,#,2}",再能够调用反序列化(Deserialize)将"{5,4,#,3,#,2}构造成如上的二叉树。

当然你也可以根据满二叉树结点位置的标号规律来序列化,还可以根据先序遍历和中序遍历的结果来序列化。不对序列化之后的字符串进行约束,所以欢迎各种奇思妙想。

数据范围:节点数 𝑛≤100,树上每个节点的值满足 0≤𝑣𝑎𝑙≤150

要求:序列化和反序列化都是空间复杂度 𝑂(𝑛),时间复杂度 𝑂(𝑛)

示例1

输入:{1,2,3,#,#,6,7}

返回值:{1,2,3,#,#,6,7}

说明:如题面图

示例2

输入:{8,6,10,5,7,9,11}

返回值:{8,6,10,5,7,9,11}

分析

序列化就是按照中序遍历的顺序,把遍历的值都放咋一个String中。其实就是层序遍历,但是不同的是遇到空值的时候在String中加入的是null

非序列化是把字符串变成二叉树,还是借助队列。

代码

java
java 复制代码
import java.util.*;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    String Serialize(TreeNode root) {
        if(root==null){
            return "[]";
        }
        StringBuilder sb=new StringBuilder("[");
        Queue<TreeNode> que=new LinkedList<>();
        que.offer(root);
        while(!que.isEmpty()){
            TreeNode temp=que.poll();
            if(temp!=null){
                sb.append(temp.val).append(",");
                que.offer(temp.left);
                que.offer(temp.right);
            }else{
                sb.append("null,");
            }
        }
        sb.deleteCharAt(sb.length()-1);
        sb.append("]");
         return sb.toString();
    }
    TreeNode Deserialize(String str) {
       if(str.equals("[]")){
        return null;
       }
       String [] s=str.substring(1,str.length()-1).split(",");
       TreeNode root=new TreeNode(Integer.parseInt(s[0]));
        Queue<TreeNode> que=new LinkedList<>();
        que.offer(root);
        int i=1;
        while(!que.isEmpty()){
            TreeNode temp=que.poll();
             if(!s[i].equals("null")){
            temp.left=new TreeNode(Integer.parseInt(s[i]));
            que.offer(temp.left);
        }
        i++;
        if(!s[i].equals("null")){
            temp.right=new TreeNode(Integer.parseInt(s[i]));
            que.offer(temp.right);
        }
        i++;
        }
       return root;
    }
}
python
python 复制代码
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
import collections
class Solution:
    def Serialize(self, root):
        # write code here
        if not root:
            return "[]"
        list=[]
        que=collections.deque([root])
        while que:
            temp=que.popleft()
            if temp:
                list.append(str(temp.val))
                que.append(temp.left)
                que.append(temp.right)
            else:
                list.append("null")
        return '[' + ','.join(list) + ']'
    def Deserialize(self, s):
        if s=="[]":
            return None
        # write code here
        s=s[1:len(s)-1]
        s=s.split(",")
        root=TreeNode(int(s[0]))
        que=collections.deque([root])
        i=1
        while que:
            temp=que.popleft()
            if s[i]!="null":
                temp.left=TreeNode(int(s[i]))
                que.append(temp.left)
            i+=1
            if s[i]!="null":
                temp.right=TreeNode(int(s[i]))
                que.append(temp.right)
            i+=1

        return root

                

重建二叉树

题目

给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。

例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示。

提示:

1.vin.length == pre.length

2.pre 和 vin 均无重复元素

3.vin出现的元素均出现在 pre里

4.只需要返回根结点,系统会自动输出整颗树做答案对比

数据范围:𝑛≤2000,节点的值 −10000≤𝑣𝑎𝑙≤10000

要求:空间复杂度 𝑂(𝑛),时间复杂度 𝑂(𝑛)

示例1

输入:[1,2,4,7,3,5,6,8],[4,7,2,1,5,3,8,6]

返回值:{1,2,3,4,#,5,6,#,7,#,#,8}

说明:返回根节点,系统会输出整颗二叉树对比结果,重建结果如题面图示

示例2

输入:[1],[1]

返回值:{1}

示例3

输入:[1,2,3,4,5,6,7],[3,2,4,1,6,5,7]

返回值:{1,2,5,3,4,6,7}

分析

首先要明白如何划分的

第一步先找先序遍历的头结点,头结点即为根节点

第二步在中序遍历中找到头结点位置,头结点左边的部分即为左子树,根节点右边的部分即为右子树

第三步在先序遍历中划分出左右子树,然后再找到左子树的根节点,继续去划分。

代码

java
java 复制代码
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param preOrder int整型一维数组 
     * @param vinOrder int整型一维数组 
     * @return TreeNode类
     */
    public TreeNode reConstructBinaryTree (int[] preOrder, int[] vinOrder) {
        // write code here
        if(preOrder.length==0 || vinOrder.length==0){
            return null;
        }
        return build(preOrder,0,preOrder.length,vinOrder,0,vinOrder.length);
    }
    public TreeNode build(int [] preOrder,int pstart,int pend,int[] vinOrder,int vstart,int vend){
        if(pend<=pstart){
            return null;
        }
        TreeNode root=new TreeNode(preOrder[pstart]);
        int i;
        for(i=vstart;i<vend;i++){
            if(vinOrder[i]==root.val){
                break;
            }
        }
        int leftvstart=vstart;
        int leftvend=i;
        int rightvstart=i+1;
        int rightvend=vend;
        int leftpstart=pstart+1;
        int leftpend=pstart+i-vstart+1;
        int rightpstart=leftpend;
        int rightpend=pend;
        root.left=build(preOrder,leftpstart,leftpend,vinOrder,leftvstart,leftvend);
        root.right=build(preOrder,rightpstart,rightpend,vinOrder,rightvstart,rightvend);

        return root;

    }
}
python
python 复制代码
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param preOrder int整型一维数组 
# @param vinOrder int整型一维数组 
# @return TreeNode类
#
class Solution:
    def reConstructBinaryTree(self , preOrder: List[int], vinOrder: List[int]) -> TreeNode:
        # write code here
        if len(preOrder)==0 or len(vinOrder)==0:
            return None
        return self.build(preOrder,0,len(preOrder),vinOrder,0,len(vinOrder))
    def build(self,preOrder: List[int], pstart:int,pend:int,vinOrder: List[int],vstart:int,vend:int) -> TreeNode:
        if pstart==pend:
            return None
        root=TreeNode(preOrder[pstart])
        i=vstart
        for i in range(vstart,vend):
            if vinOrder[i]==root.val:
                break
        leftvstart=vstart
        leftvend=i
        rightvstart=i+1
        rightvend=vend
        leftpstart=pstart+1
        leftpend=i-vstart+pstart+1
        rightpstart=leftpend
        rightpend=pend
        root.left=self.build(preOrder,leftpstart,leftpend,vinOrder,leftvstart,leftvend)
        root.right=self.build(preOrder,rightpstart,rightpend,vinOrder,rightvstart,rightvend)
        return root

输出二叉树的右视图

题目

请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图

数据范围: 0≤𝑛≤10000

要求: 空间复杂度 𝑂(𝑛),时间复杂度 𝑂(𝑛)

如输入[1,2,4,5,3],[4,2,5,1,3]时,通过前序遍历的结果[1,2,4,5,3]和中序遍历的结果[4,2,5,1,3]可重建出以下二叉树:

所以对应的输出为[1,3,5]。

示例1

输入:[1,2,4,5,3],[4,2,5,1,3]

返回值:[1,3,5]

备注:二叉树每个节点的值在区间[1,10000]内,且保证每个节点的值互不相同。

分析

把构建二叉树和层序遍历结合到一起了!

只不过只记录每一层的最后一个节点即可

代码

java
java 复制代码
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 求二叉树的右视图
     * @param preOrder int整型一维数组 先序遍历
     * @param inOrder int整型一维数组 中序遍历
     * @return int整型一维数组
     */
    public int[] solve (int[] preOrder, int[] inOrder) {
        // write code here
        List<Integer> result=new LinkedList<>();
        if(preOrder.length==0 || inOrder.length==0){
            return new int[0];
        }
        TreeNode root=build(preOrder,0,preOrder.length,inOrder,0,inOrder.length);
        Deque<TreeNode> que=new LinkedList<>();
        que.offer(root);
        while(!que.isEmpty()){
            int len=que.size();
            while(len-->0){
            TreeNode temp=que.poll();
            if(len==0){
                result.add(temp.val);
            }
            if(temp.left!=null){
                que.offer(temp.left);
            }
            if(temp.right!=null){
                que.offer(temp.right);
            }
            }

    }
         int[] res = new int[result.size()];
        for(int i = 0; i < result.size(); i++){
            res[i] = result.get(i);
        }
        return res;
        }
     public TreeNode build(int[] preOrder,int pstart,int pend,int[] vinOrder,int vstart,int vend){
        if(pstart==pend){
            return null;
        }
        TreeNode root=new TreeNode(preOrder[pstart]);
        int i;
        for(i=vstart;i<vend;i++){
            if(vinOrder[i]==root.val){
                break;
            }
        }
        int leftvstart=vstart;
        int leftvend=i;
        int rightvstart=i+1;
        int rightvend=vend;
        int leftpstart=pstart+1;
        int leftpend=i-leftvstart+1+pstart;
        int rightpstart=leftpend;
        int rightpend=pend;
        root.left=build(preOrder,leftpstart,leftpend,vinOrder,leftvstart,leftvend);
        root.right=build(preOrder,rightpstart,rightpend,vinOrder,rightvstart,rightvend);
        return root;
    }
}
python
python 复制代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 求二叉树的右视图
# @param preOrder int整型一维数组 先序遍历
# @param inOrder int整型一维数组 中序遍历
# @return int整型一维数组
#
from typing import List
import collections 
class Solution:
    def solve(self , preOrder: List[int], inOrder: List[int]) -> List[int]:
        if not preOrder or not inOrder:
            return []
        
        # 重建二叉树
        root = self.build(preOrder, 0, len(preOrder), inOrder, 0, len(inOrder))
        
        # 层序遍历求右视图
        res = []
        q = collections.deque()
        q.append(root)
        
        while q:
            level_size = len(q)
            # 遍历当前层
            for i in range(level_size):
                node = q.popleft()
                # 每层最后一个节点 → 右视图
                if i == level_size - 1:
                    res.append(node.val)
                
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
        
        return res
    
    # 重建二叉树(完全按照你的 Java 逻辑翻译)
    def build(self, preOrder: List[int], pstart: int, pend: int, vinOrder: List[int], vstart: int, vend: int) -> TreeNode:
        if pstart == pend:
            return None
        
        root = TreeNode(preOrder[pstart])
        
        # 在中序遍历中找到根节点位置
        i = vstart
        while i < vend:
            if vinOrder[i] == root.val:
                break
            i += 1
        
        # 左、右子树区间(和你 Java 一模一样)
        leftvstart = vstart
        leftvend = i
        rightvstart = i + 1
        rightvend = vend
        
        leftpstart = pstart + 1
        leftpend = i - vstart + pstart + 1
        rightpstart = leftpend
        rightpend = pend
        
        # 递归构造
        root.left = self.build(preOrder, leftpstart, leftpend, vinOrder, leftvstart, leftvend)
        root.right = self.build(preOrder, rightpstart, rightpend, vinOrder, rightvstart, rightvend)
        
        return root

总结

二叉树一般来说用递归很多,把他的左右子树相成一块一块的问题,再去思考。

相关推荐
6Hzlia1 小时前
【Hot 100 刷题计划】 LeetCode 98. 验证二叉搜索树 | C++ 指针边界法
c++·算法·leetcode
Frank学习路上1 小时前
【Python】应用:发布pyproject.toml格式包到 PyPI
开发语言·chrome·python
AI科技星2 小时前
算子数学|独立完整学科章节(百条原创公式· ROOT传世定稿)
大数据·算法·机器学习·数学建模·数据挖掘·量子计算
阿标的博客2 小时前
Python学习(三):Python程序的运行方式
开发语言·python·学习
IMPYLH2 小时前
Linux 的 split 命令
linux·运维·python·bash·运维开发·unix
0xDevNull2 小时前
分布式事务实战指南:从理论到Seata落地
java·开发语言·后端
z4424753262 小时前
MySQL如何配置自动清理失效事务锁_结合定时任务清理
jvm·数据库·python
斯维赤2 小时前
每天学习一个小算法:堆排序
学习·算法·排序算法
椰猫子2 小时前
Spring Framework(Bean)
java·前端·spring