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. java内存机制 垃圾回收

    gc机制一 1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc ...

  2. HBase从入门到精通系列:误删数据如何抢救?

    云栖君导读:有时候我们操作数据库的时候不小心误删数据,这时候如何找回?mysql里有binlog可以帮助我们恢复数据,但是没有开binlog也没有备份就尴尬了.如果是HBase,你没有做备份误删了又如 ...

  3. mysql第四篇:数据操作之单表查询

    单表查询 一.简单查询 -- 创建表 DROP TABLE IF EXISTS `person`; CREATE TABLE `person` ( `id` ) NOT NULL AUTO_INCRE ...

  4. Multiarmed Bandit Algorithm在股票中的应用

    股票与Bandit Machine看起来相去甚远,但实际上通过限制买入和卖出的行为,股票可以转换为Bandit Machine,比如:规定股票必须在买入一天以后卖出.为什么要大费周折地把股票变成Ban ...

  5. JavaScript—纯函数

    定义 一个函数的返回结果只依赖它的参数,而且在计算过程中不会产生其他副作用,也就是不会对外部的数据造成影响或改变. 理解:函数的返回结果只依赖它的参数 const a= 1; const b= (c) ...

  6. 2020/1/31 PHP代码审计之目录穿越漏洞

    0x00 目录穿越 目录穿越(Directory Traversal)攻击是黑客能够在Web应用程序所在的根目录以外的文件夹上,任意的存取被限制的文件夹,执行命令或查找数据.目录穿越攻击,也与人称为P ...

  7. QEMU和Firmadyne基本知识|模拟MIPS程序

    QEMU QEMU是纯软件实现的一个虚拟化模拟器,几乎可以模拟任何硬件设备,支持多种架构. QEMU安装命令 sudo apt-get install qemu #user mode,包含qemu-m ...

  8. python基础1--基本数据类型+流程控制

      一.基本数据类型 1.整型 int 就是整数   2.浮点型 float 就是小数     3.字符串 3.1.加了单引号.双引号.多引号的字符就认为是字符串 单引号和双引号没有什么区别,多引号用 ...

  9. .equal()和==的区别

    1.首先,equal和==最根本的区别在于equal是一个方法,而==是一个运算符. 2.一般来说,==运算符比较的是在内存中的物理地址,.equal()比较的是哈希算法值是否相等(即hashcode ...

  10. CAD快捷键大全