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);
}
}