1.求二叉树的深度或者说最大深度
/*
***1.求二叉树的深度或者说最大深度
*/
public static int maxDepth(TreeNode root){
if(root==null) return 0;
int left=maxDepth(root.left);
int right=maxDepth(root.right);
return Math.max(left,right)+1;
} 2.求二叉树的最小深度
/*
***2.求二叉树的最小深度
*/
public static int MinDepth(TreeNode root){
if(root==null) return 0;
if(root.left==null&&root.right==null) return 1;
int left=MinDepth(root.left);
int right=MinDepth(root.right);
if(root.left==null||root.right==null) return Math.max(left,right)+1;
return Math.min(left,right)+1;
} 3.求二叉树中节点的个数
/*
***3.求二叉树中节点的个数
*/
public static int nodeCount(TreeNode root){
if(root==null) return 0;
int left=nodeCount(root.left);
int right=nodeCount(root.right);
return left+right+1;
} 4.求二叉树中叶子节点的个数
/*
***4.求二叉树中叶子节点的个数
*/
public static int leafNodeCount(TreeNode root){
if(root==null) return 0;
if(root.left==null&&root.right==null) return 1;
int left=leafNodeCount(root.left);
int right=leafNodeCount(root.right);
return left+right;
} 5.求二叉树中第k层节点的个数
/*
***5.求二叉树中第k层节点的个数
*/
public static int KlevelCount(TreeNode root,int k){
if(root==null||k<1) return 0;
if(k==1) return 1; //K=1的那一层总是我们想找的那一层
int left=KlevelCount(root.left,k-1);
int right=KlevelCount(root.right,k-1);
return left+right; //或者可以用层次遍历的方法
} 6.判断二叉树是否为平衡二叉树
/*
***6.判断二叉树是否为平衡二叉树 平衡二叉树的左右子树高度差的不超过1
*/
public static boolean isBalancedTree(TreeNode root){
if(root==null) return false;
return isBalancedhelper(root)!=-1;
}
public static int isBalancedhelper(TreeNode root){
if(root==null) return 0;
int left=isBalancedhelper(root.left);
int right=isBalancedhelper(root.right);
if(Math.abs(left-right)>1) return -1; //返回-1说明不平衡
return Math.max(left,right)+1;
} 7.判断二叉树是否是二叉完全树
/*
***7.判断二叉树是否是二叉完全树
*/
public static boolean isCompleteTree(TreeNode root){
if(root==null) return false;
Queue<TreeNode> queue=new LinkedList<>();
queue.add(root);
boolean res=true;
boolean hasNoChild=false;
while(!queue.isEmpty()){
TreeNode tmp=queue.remove();
if(hasNoChild){ //hasNoChild=true说明在tmp节点之前有无右孩子的节点,这时tmp只能为叶子节点
if(tmp.left!=null||tmp.right!=null) return false;
}
else{
if(tmp.left!=null&&tmp.right!=null){
queue.add(tmp.left);
queue.add(tmp.right);
}
else if(tmp.left!=null&&tmp.right==null){
queue.add(tmp.left);
hasNoChild=true;
}
else if(tmp.left==null&&tmp.right!=null) return false;
else hasNoChild=true;
}
}
return res;
} 8.两个二叉树是否完全相同
/*
***8.两个二叉树是否完全相同
*/
public static boolean isSameTree(TreeNode root1,TreeNode root2){
if(root1==null) return root2==null;
if(root2==null) return false;
if(root1.val!=root2.val) return false;
return isSameTree(root1.left,root2.left)&&isSameTree(root1.right,root2.right);
} 9.两个二叉树是否为镜像二叉树
/*
***9.两个二叉树是否为镜像二叉树
*/
private static boolean isMirror(TreeNode root1,TreeNode root2){
if(root1==null) return root2==null; //如果是判断某棵树是不是镜像的,令root2=root1即可
if(root2==null) return false;
if(root1.val!=root2.val) return false;
return isMirror(root1.left,root2.right)&&isMirror(root1.right,root2.left);
} 10.翻转二叉树或者镜像二叉树
/*
***10.翻转二叉树或者镜像二叉树
*/
private static boolean mirrorTree(TreeNode root){
if(root==null) return root;
TreeNode left=mirrorTree(root.left); //先把左右子树都先翻转
TreeNode right=mirrorTree(root.right);
root.left=right; //再把左右孩子节点反转
root.right=left;
return root;
} 11.求两个二叉树节点的最低公共祖先节点
/*
***11.求两个二叉树节点的最低公共祖先节点
*/
private static TreeNode lastCommonParent(TreeNode root,TreeNode node1,TreeNode node2){
if(!lastCommonParentHelper(root,node1)||!lastCommonParentHelper(root,node2)) return null;
if(lastCommonParentHelper(root.left,node1)){ //node1在左子树上
//
if(lastCommonParentHelper(root.left,node2)) return lastCommonParent(root.left,node1,node2); //去root的左子树上看看
else {
return root;//否则,1.如果两个节点分居root的两个子树,那么root就是最近父节点 2.node2是根节点或者右边的节点,那么公共节点一定是root
}
}
else if(lastCommonParentHelper(root.right,node1)){ //node1不在左子树上,而在右子树上
//如果node2也在右子树上,那么就去右子树看看
if(lastCommonParentHelper(root.right,node2)) return lastCommonParent(root.right,node1,node2);
else{
return root; //node2不在右子树,那么可能在root或者左子树,则root是最近根节点
}
}
else return root;
}
private static boolean lastCommonParentHelper(TreeNode root,TreeNode node){ //判断node是不是root的子结构
if(root==null||node=null) return false; //约定null不是任何树的子树
if(root==node) return true;
return lastCommonParentHelper(root.left,node)||lastCommonParentHelper(root.right,node);
} 12.二叉树的前序遍历
/*
***12.二叉树的前序遍历 用ArrayList<Integer>存储
*/
private static ArrayList<Integer> preOrder(TreeNode root){
ArrayList<Integer> list=new ArrayList<>();
preOrder1(root,list);
//preOrder2(root,list)
return list;
}
//先序遍历的递归写法
private static void preOrder1(TreeNode root,ArrayList<Integer> list){
if(root==null) return ;
list.add(root.val);
preOrder1(root.left,list);
preOrder1(root.right,list);
}
//先序遍历的迭代写法
private static void preOrder2(TreeNode root,ArrayList<Integer> list){
if(root==null) return ;
Stack<Integer> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode tmp=stack.pop();
list.add(tmp.val);
if(tmp.right!=null) stack.push(tmp.right); //先把右节点入栈,这样出栈的时候总是左节点先读取
if(tmp.left!=null) stack.push(tmp.left);
}
return ;
} 13.二叉树的中序遍历
/*
***13.二叉树的中序遍历 用ArrayList<Integer>存储
*/
private static ArrayList<Integer> inOrder(TreeNode root){
ArrayList<Integer> list=new ArrayList<>();
inOrder1(root,list);
//inOrder2(root,list)
return list;
}
//中序遍历的递归写法
private static void inOrder1(TreeNode root,ArrayList<Integer> list){
if(root==null) return ;
inOrder1(root.left,list);
list.add(root.val);
inOrder1(root.right,list);
}
//中序遍历的迭代写法
private static void inOrder(TreeNode root,ArrayList<Integer> list){
if(root==null) return ;
Stack<Integer> stack=new Stack<>();
TreeNode p=root;
while(p!=null||!stack.isEmpty()){
while(p!=null){
stack.push(p);
p=p.left;
}
p=stack.pop();
list.add(p.val);
p=p.right;
}
return ;
} 14.二叉树的后序遍历
/*
***14.二叉树的后序遍历 用ArrayList<Integer>存储
*/
private static ArrayList<Integer> postOrder(TreeNode root){
ArrayList<Integer> list=new ArrayList<>();
postOrder1(root,list);
//postOrder2(root,list)
return list;
}
//先序遍历的递归写法
private static void postOrder1(TreeNode root,ArrayList<Integer> list){
if(root==null) return ;
postOrder1(root.left,list);
postOrder1(root.right,list);
list.add(root.val);
}
//后序遍历的迭代写法
private static void postOrder2(TreeNode root,ArrayList<Integer> list){
if(root==null) return ;
Stack<Integer> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode tmp=stack.pop();
list.add(tmp.val);
if(tmp.left!=null) stack.push(tmp.left); //先把左节点入栈,这样出栈的时候总是右节点先读取
if(tmp.right!=null) stack.push(tmp.right); //进组的顺序为 根->右->左 正好和后续遍历的顺序相反
} Collections.reverse(list); //反转list即可
return ;
} 15.二叉树的层次遍历
/*
***15.二叉树的层次遍历
*/
private static ArrayList<ArrayList<Integer>> leverOrder(TreeNode root){
ArrayList<ArrayList<Integer>> listAll=new ArrayList<>();
if(root==null) return listAll;
ArrayList<Integer> list=new ArrayList<Integer>();
Queue<TreeNode> queue=new LinkedList<>();
queue.add(root);
int count=0,nextCount=1;
while(!queue.isEmpty()){
TreeNode tmp=queue.remove();
list.add(tmp.val);
count++;
if(tmp.left!=null) queue.add(tmp.left);
if(tmp.right!=null) queue.add(tmp.right);
if(count==nextCount){
count=0;
nextCount=queue.size();
listAll.add(new ArrayList<Integer>(list));
list.clear();
}
}
return listAll;
} 16.先序遍历和中序遍历构造二叉树
/*
***16.先序遍历和中序遍历构造二叉树
*/
private static TreeNode pre_in_BuildTree(int[] preorder,int[] inorder){
if(preorder.length!=inorder.length) return null;
return pre_in_BuildTreeHelper(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
private static TreeNode pre_in_BuildTreeHelper(int[] preorder,int preStart,int preEnd,int[] inorder,int inStart,int inEnd){
if(preStart>preEnd) return null;
TreeNode root=new TreeNode(preorder[preStart]);
int index=inStart;
while(inorder[index]!=root.val) index++;
root.left=pre_in_BuildTreeHelper(preorder,preStart+1,preStart+index-inStart,inorder,inStart,index-1);
root.right=pre_in_BuildTreeHelper(preorder,preStart+index-inStart+1,preEnd,inorder,index+1,inEnd);
return root;
} 17.中序遍历和后续遍历构造二叉树
/*
***17.中序遍历和后续遍历构造二叉树
*/
private static TreeNode in_post_BuildTree(int[] inorder,int[] postorder){
if(postorder.length!=inorder.length) return null;
return in_post_BuildTreeHelper(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
}
private static TreeNode in_post_BuildTreeHelper(int[] inorder,int inStart,int inEnd,int[] postorder,int postStart,int postEnd,){
if(postStart>postEnd) return null;
TreeNode root=new TreeNode(postorder[postEnd]);
int index=inStart;
while(inorder[index]!=root.val) index++;
root.left=in_post_BuildTreeHelper(inorder,inStart,index-1,postorder,postStart,postStart+index-inStart-1);
root.right=in_post_BuildTreeHelper(inorder,index+1,inEnd,postorder,postStart+index-inStart,postEnd-1);
return root;
} 18.输入一个二叉树和一个整数,打印出从二叉树根节点到叶子节点的路径上所有节点值之和值等于输入整数所有的路径
/*
***18.输入一个二叉树和一个整数,打印出从二叉树根节点到叶子节点的路径上所有节点值之和值等于输入整数所有的路径
*/
private static ArrayList<ArrayList<Integer>> findPath(TreeNode root, int target){
ArrayList<ArrayList<Integer>> listAll=new ArrayList<>();
if(root==null) return listAll;
ArrayList<Integer> list=new ArrayList<>();
findPathHelper(root,target,listAll,list);
return listAll;
}
private static void findPathHelper(TreeNode root, int target,ArrayList<ArrayList<Integer>> listAll,ArrayList<Integer> list){
if(root==null) return ;
list.add(root.val);
if(root.left==null&&root.right==null&&target==root.val) listAll.add(new ArrayList<Integer>(list));
findPathHelper(root.left,target-root.val,listAll,list);
findPathHelper(root.right,target-root.val,listAll,list);
list.remove(list.size()-1);
} 19.二叉搜索树的第k小的节点(中序遍历解决)
/*
***19.二叉搜索树的第k小的节点(中序遍历解决)
*/
private static TreeNode KthNode(TreeNode pRoot, int k)
{
if(pRoot==null||k==0) return null;
Stack<TreeNode> stack=new Stack<>();
int count=0;
TreeNode p=pRoot;
while(p!=null||!stack.isEmpty()){
while(p!=null){
stack.push(p);
p=p.left;
}
p=stack.pop();
if(++count==k) return p;
p=p.right;
}
return null;
} 20.输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
/*
***20.输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
*/
private static boolean VerifySquenceOfBST(int [] sequence) {
if(sequence.length==0) return false;
if(sequence.length==1) return true;
return isBST(sequence,0,sequence.length-1);
}
private static boolean isBST(int[] num,int start,int end){
if(start>=end) return true;
int i=start;
while(num[i]<num[end]) i++;
for(int j=i;j<end;j++){
if(num[j]<num[end]) return false;
}
return isBST(num,start,i-1)&&isBST(num,i,end-1);
} 21.给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。
/*
***21.给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。
***注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
*/
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null; //指向其父节点
TreeLinkNode(int val) {
this.val = val;
}
}
private static TreeLinkNode GetNext(TreeLinkNode pNode)
{
if(pNode==null) return null;
if(pNode.right!=null){
pNode=pNode.right;
while(pNode.left!=null){
pNode=pNode.left;
}
return pNode;
}
while(pNode.next!=null){
if(pNode.next.left==pNode) return pNode.next;
pNode=pNode.next;
}
return null;
} 22.判断二叉树是不是二叉搜索树
/*
***22.判断二叉树是不是二叉搜索树
*/
private static boolean isBST(TreeNode root){
if(root==null) return false; //约定空树不是二叉搜索树
return isBSThelper(root,Long.MIN_VALUE,Long.MAX_VALUE);
}
private static boolean isBSThelper(TreeNode root,long low,long high){
if(root==null) return true;
if(root.val<low||root.val>high) return false;//这里加不加等号取决于具体的二叉搜索树定义,如果不允许相等的值存在则加上等号
return isBSThelper(root.left,low,root.val)&&isBSThelper(root.right,root.val,high);
} 23.求二叉树中节点的最大距离
/*
***23.求二叉树中节点的最大距离
*/
private static int maxDistance=Integer.MIN_VALUE;
private static int getMaxDistance(TreeNode root){
if(root==null) return 0;
getMaxDistanceHelper(root);
return maxDistance;
}
private static int getMaxDistanceHelper(TreeNode root){
if(root==null) return -1;
int leftMaxDistance=getMaxDistanceHelper(root.left);
int rightMaxDistance=getMaxDistanceHelper(root.right);
int temptMaxDistance=leftMaxDistance+rightMaxDistance+2;
if(temptMaxDistance>maxDistance) maxDistance=temptMaxDistance;
return leftMaxDistance>rightMaxDistance?leftMaxDistance+1:rightMaxDistance+1;
} 24.合并两棵二叉树 /*
***24.合并两棵二叉树
*/
private static TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if(t2==null) return t1;
if(t1==null) return t2;
TreeNode root=new TreeNode(t1.val+t2.val);
root.left=mergeTrees(t1.left,t2.left);
root.right=mergeTrees(t1.right,t2.right);
return root;
}

面试常见二叉树算法题集锦-Java实现的更多相关文章

  1. 常见排序算法题(java版)

    常见排序算法题(java版) //插入排序:   package org.rut.util.algorithm.support;   import org.rut.util.algorithm.Sor ...

  2. 面试经典算法题集锦——《剑指 offer》小结

    从今年 3 月份开始准备找实习,到现在校招结束,申请的工作均为机器学习/数据挖掘算法相关职位,也拿到了几个 sp offer.经历这半年的洗礼,自己的综合能力和素质都得到了一个质的提升. 实话说对于未 ...

  3. 大公司面试经典数据结构与算法题C#/Java解答

    几个大公司(IBM.MicroSoft and so on)面试经典数据结构与算法题C#解答 1.链表反转 我想到了两种比较简单的方法 第一种是需要开一个新的链表,将原链表的元素从后到前的插入到新链表 ...

  4. [2]十道算法题【Java实现】

    前言 清明不小心就拖了两天没更了-- 这是十道算法题的第二篇了-上一篇回顾:十道简单算法题 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下, ...

  5. 提前批笔试一道算法题的Java实现

    题目描述 这是2021广联达校招提前批笔试算法题之一. 我们希望一个序列中的元素是各不相同的,但是理想和显示往往是有差距的.现在给出一个序列A,其中难免有相同的元素,现在提供了一种变化方式,使得经过若 ...

  6. 数据结构笔记02:Java面试必问算法题

    1. 面试的时候,栈和队列经常会成对出现来考察.本文包含栈和队列的如下考试内容: (1)栈的创建 (2)队列的创建 (3)两个栈实现一个队列 (4)两个队列实现一个栈 (5)设计含最小函数min()的 ...

  7. JS数据结构与算法 - 剑指offer二叉树算法题汇总

    ❗❗ 必看经验 在博主刷题期间,基本上是碰到一道二叉树就不会碰到一道就不会,有时候一个下午都在搞一道题,看别人解题思路就算能看懂,自己写就呵呵了.一气之下不刷了,改而先去把二叉树的基础算法给搞搞懂,然 ...

  8. 常见排序算法总结(java版)

    一.冒泡排序 1.原理:相邻元素两两比较,大的往后放.第一次完毕,最大值在最大索引处. 即使用相邻的两个元素一次比价,依次将最大的数放到最后. 2.代码: public static void bub ...

  9. 面试10大算法汇总+常见题目解答(Java)

    原文地址:http://www.lilongdream.com/2014/04/10/94.html(为转载+整理) 以下从Java的角度总结了面试常见的算法和数据结构:字符串,链表,树,图,排序,递 ...

随机推荐

  1. 转:JS高级学习笔记(8)- JavaScript执行上下文和执行栈

    必看参考: 请移步:博客园 JavaScript的执行上下文 深入理解JavaScript执行上下文和执行栈 JavaScript 深入之执行上下文 写在开头 入坑前端已经 13 个月了,不能再称自己 ...

  2. mariadb主从

    实验环境: 两台centos7 master:192.168.1.6 slave:192.168.1.7 一.安装mariadb服务 [root@master ~]# yum -y install m ...

  3. xxe

    XXE xml external entity injection xml外部实体注入 概述 xml是可扩展的标记语言,涉及被用来传输.存储数据 html被用来显示数据 其中xml的标签没有预定义的, ...

  4. springboot--入门(了解springboot)

    个人认为,springboot和maven差不多.maven方便我们管理jar包,而springboot帮助我们简化spring的配置. 未完,待续.......

  5. 程序员用 Python 扒出 B 站那些“惊为天人”的UP主!

    ​ 前言 ! 近期B站的跨年晚会因其独特的创意席卷各大视频网站,给公司带来了极大的正面影响,股价也同时大涨,想必大家都在后悔没有早点买B站的股票: ​ 然而今天我们要讨论的不是B站的跨年晚会,而是B站 ...

  6. 设置MySQL客户端连接使用的字符集

    设置MySQL客户端连接使用的字符集 时间:2014-03-05    来源:服务器之家    投稿:root 考虑什么是一个"连接":它是连接服务器时所作的事情.客户端发送SQL ...

  7. Flux转Mono next()

    import java.util.LinkedHashMap; import java.util.Map; import java.util.NoSuchElementException; impor ...

  8. 双向链表的双向冒泡排序 c++

    #include<iostream> using namespace std; #define swap(a,b) {int t;t = a;a = b;b = t;} //节点类型的定义 ...

  9. Python—程序设计:观察者模式

    观察者模式 内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新.观察者模式又称“发布-订阅”模式. 角色: 抽象主题(Subject) 具体 ...

  10. Java--Excel操作

    public static List<Info> readXml(String fileName, Map<String, Fuck> pcMap) throws Except ...