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. qt 程序发布打包

    1. 首先把 release 版本的 exe 复制到其他文件夹,比如 Desktop\test 2. 使用开始菜单中 qt 里面的控制台窗口,使用 cd 命令打开到 Desktop\test 位置,然 ...

  2. leetcode406 ,131,1091 python

    LeetCode 406. Queue Reconstruction by Height 解题报告题目描述Suppose you have a random list of people standi ...

  3. jdk8安装

    ==安装jdk1.8== [root@ycj ~]# mkdir -p /usr/local/src/jdk //创建目录 [root@ycj jdk]# cd /usr/local/src/jdk ...

  4. mybatis的批量update

    方法有三种:1.通过java代码batch方式,xml文件只需一条update语句.java代码繁琐 2.xml使用foreach,“;”分割多条update语句,要求:jdbc的url需加上allo ...

  5. 转载电子发烧友网---STM32的IO口灌入电流和输出驱动电流

    刚开始学习一款单片机的时候一般都是从操作IO口开始的,所以我也一样,先是弄个流水灯. 刚开始我对STM32的认识不够,以为是跟51单片机类似,可以直接操作端口,可是LED灯却没反应,于是乎,仔细查看资 ...

  6. JZOJ-2019-11-7 A组

    T1 Input 从文件 awesome.in 中读入数据. 第一行 2 个用空格隔开的整数 \(n\), \(P\). 第二行 n 个用空格隔开的整数 \(A_1, \cdots , A_n\). ...

  7. 【收藏】免费开源好看的bootstrap后台模板

    1.ace admin github:https://github.com/bopoda/acedemo:http://ace.jeka.by/ 2.CoreUI jQuery.Angular.Rea ...

  8. 工程日记之HelloSlide(3):如何使用Core Data数据库,以及和sqlite之间的对应关系

    Core Data 和 SQLite 是什么关系 core data是对sqlite的封装,因为sqlite是c语言的api,然而有人也需要obj-c的api,所以有了core data ,另外,co ...

  9. nfs自动挂载

    服务器端 /etc/exports /mnt *(rw,sync,no_root_squash,anonuid=500,anongid=500)systemctl restart nfs 客户端 挂载 ...

  10. github新建一个单页

    比如可以在github上打开的网页是这种网址形式的:https://01xunsicheng.github.io/yumeihua/ 1.登录后首页找到 New repository 2.新建一个文件 ...