2021-10-20

JZ55 二叉树的深度

题目地址
描述
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
示例1

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

方法一 :递归

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 int TreeDepth(TreeNode root) {
        if(root==null){
            return 0;
        }
        int leftHeight=TreeDepth(root.left);
        int rightHeight=TreeDepth(root.right);
        return Math.max(leftHeight,rightHeight)+1;
    }
}

方法二:未完待续

JZ77 按之字形顺序打印二叉树

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

数据范围:0 <= n <= 15000≤n≤1500,树上每个节点的val满足 |val| <= 100
要求:空间复杂度:O(n) ,时间复杂度:O(n)
例如:
给定的二叉树是{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]]

代码
思路
使用一个map集合,用于记录结点所在的层次(层数从1开始标记,即根节点层号为1),一个res集合记录结果,kept集合记录二叉树同一层的节点,一个变量nowLen,记录当前访问二叉树的层号,初始化为1。
当res加入kept时,若kept中记录的结点的层号是偶数,则反转后再加入到res中。

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 ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        //记录结果
        ArrayList<ArrayList<Integer>> res=new ArrayList<>();
        if(pRoot==null){
            return res;
        }
        //队列
        Queue<TreeNode> q=new LinkedList<>();
        q.add(pRoot);
        //map,映射某一结点对于那一层
        Map<TreeNode,Integer> map=new HashMap<>();
        map.put(pRoot,1);
        //记录当前遍历到的结点
        TreeNode tmp=null;
        //记录当前遍历的的层次
        int nowLen=1;
        //临时数组,存放结果
        ArrayList<Integer> kept=new ArrayList<>();
        while(!q.isEmpty()){
            tmp=q.poll();
            //同一层次遍历
            if(map.get(tmp)==nowLen){
                kept.add(tmp.val);
            }else{//新开启一层
                // add时,若nowLen为奇数,则直接加入,如果为偶数,则反转后再加入
                if(nowLen%2 == 0){
                    reverse(kept);
                }
                res.add(kept);
                kept=new ArrayList<>();
                kept.add(tmp.val);
                nowLen++;
            }
            if(tmp.left!=null){
                q.add(tmp.left);
                map.put(tmp.left,map.get(tmp)+1);
            }
            if(tmp.right!=null){
                q.add(tmp.right);
                map.put(tmp.right,map.get(tmp)+1);
            }
        }
        //最后一组数组的保存,不要忘记偶数反转
        if(nowLen%2==0){
            reverse(kept);
        }
        res.add(kept);
        return res;
    }
    public void reverse(ArrayList<Integer> list){
        int i=0,j=list.size()-1;
        while(i<j){
            swap(list,i,j);
            i++;
            j--;
        }
    }
    public void swap(ArrayList<Integer> list,int i,int j){
        int tmp=list.get(i);
        list.set(i,list.get(j));
        list.set(j,tmp);
    }
}

JZ54 二叉搜索树的第k个结点

题目地址
描述
给定一棵结点数为 n 二叉搜索树,请找出其中的第 k 小的TreeNode结点。

数据范围: 0≤n<=100,0≤k≤100,树上每个结点的值满足 0≤val≤100
要求:空间复杂度 O(1),时间复杂度 O(n)

注意:不是返回结点的值

如输入{5,3,7,2,4,6,8},3时,二叉树{5,3,7,2,4,6,8}如下图所示:
在这里插入图片描述
该二叉树所有节点按结点值升序排列后可得[2,3,4,5,6,7,8],所以第3个结点的结点值为4,故返回对应结点值为4的结点即可。
输入描述
提示:当n为0或者k为0时返回空。
示例1

输入:
{5,3,7,2,4,6,8},3
返回值:
4
说明:
按结点数值升序顺序可知第三小结点的值为4 ,故返回对应结点值为4的结点即可。    

示例2

输入:
{},1
返回值:
"null"
说明:
结点数n为0,所以返回对应编程语言的空结点即可。 

代码:
思路:利用二叉搜索树中序遍历升序的规律,设置一个变量,用于记录访问到第几个结点,直到访问到第k个结点。
此处利用中序非递归遍历

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 {
    TreeNode KthNode(TreeNode pRoot, int k) {
        if(pRoot==null||k<=0){
            return null;
        }
        //二叉搜索树,中序遍历升序排列
        Stack<TreeNode> stack=new Stack<>();
        TreeNode head=pRoot;
        TreeNode res=null;
        int count=0;
        while(!stack.isEmpty() || head!=null){//不要犯错误写成 stack!=null
            if(head!=null){
                stack.push(head);
                head=head.left;
            }else{
                head=stack.pop();
                count++;
                if(count==k){
                   res=head;
                   break;
                }
                head=head.right;
            }
        }
        return res;
    }
}

JZ7 重建二叉树

题目地址
描述
给定节点数为 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.只需要返回根结点,系统会自动输出整颗树做答案对比
数据范围:n≤2000,节点的值−10000≤val≤10000
要求:空间复杂度 O(n),时间复杂度 O(n)
示例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}

代码

import java.util.*;
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] vin) {
        if(pre==null||pre.length==0||vin==null||vin.length==0){
            return null;
        }
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<vin.length;i++){
            map.put(vin[i],i);
        }
        TreeNode head=new TreeNode(pre[0]);
        reConstructBinaryTree2(pre,0,pre.length-1,vin,0,vin.length-1,head,map);
        return head;
    }
    public void reConstructBinaryTree2(int[] pre,int pi,int pj,
                                       int[] vin,int vi,int vj,
                                       TreeNode now,
                                       HashMap<Integer,Integer> map){
        if(pi>=pj){
            return;
        }
        //先序值对应在中序中的位置
        int i=map.get(pre[pi]);
        if(pi+1<=pj && i-1>=vi) now.left=new TreeNode(pre[pi+1]);
        if(pi+i-vi+1<=pj &&i+1<=vj) now.right=new TreeNode(pre[pi+i-vi+1]);
        reConstructBinaryTree2(pre,pi+1,pi+i-vi,vin,vi,i-1,now.left,map);
        reConstructBinaryTree2(pre,pi+i-vi+1,pj,vin,i+1,vj,now.right,map);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值