面试大总结之二:Java搞定面试中的二叉树题目

47面试常问:六大类二叉树面试题汇总解答 0 概述 继上一篇总结了二叉树的基础操作后,这一篇文章汇总下常见的二叉树相关面试题,主要分为判断类、构建类、存储类、查找类、距离类、混合类这六类大问题。 本文所有代码 https://github.com/shishujuan/dsalg/tree/master/code/ds/tree/binary_tree 1 判断类问题 判断类问题主要分下下判断二叉树是否是二叉搜索树、二叉完全树,以及两棵二叉树是否同构这三个问题。 1.1 判断一棵二叉树是否是二叉搜索树(BST) 题:给定... 阅读详情

这是本系列的第二篇,与前一篇 面试大总结之一:Java搞定面试中的链表题目 相比,二叉树的题目可以变化的就更多了。本文还是参考整合重写了《轻松搞定面试中的二叉树题目》和《算法大全(3) 二叉树》两篇大作。本文一个小亮点就是几乎每一道题都用了递归和迭代两种方法写过一遍,因为面试时往往可能会被要求写不擅长的那一种。这一千多行的记录也是我在面试摸索过程中的一个小笔记,备份与此。请大神们轻拍指正。今后我也会不断更新加入新题新方法。


package BinaryTreeSummary;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;

/**
 * http://blog.youkuaiyun.com/luckyxiaoqiang/article/details/7518888  轻松搞定面试中的二叉树题目
 * http://www.cnblogs.com/Jax/archive/2009/12/28/1633691.html  算法大全(3) 二叉树
 * 
 * TODO: 一定要能熟练地写出所有问题的递归和非递归做法!
 *
 * 1. 求二叉树中的节点个数: getNodeNumRec(递归),getNodeNum(迭代)
 * 2. 求二叉树的深度: getDepthRec(递归),getDepth 
 * 3. 前序遍历,中序遍历,后序遍历: preorderTraversalRec, preorderTraversal, inorderTraversalRec, postorderTraversalRec
 * (https://en.wikipedia.org/wiki/Tree_traversal#Pre-order_2)
 * 4.分层遍历二叉树(按层次从上往下,从左往右): levelTraversal, levelTraversalRec(递归解法!)
 * 5. 将二叉查找树变为有序的双向链表: convertBST2DLLRec, convertBST2DLL
 * 6. 求二叉树第K层的节点个数:getNodeNumKthLevelRec, getNodeNumKthLevel
 * 7. 求二叉树中叶子节点的个数:getNodeNumLeafRec, getNodeNumLeaf
 * 8. 判断两棵二叉树是否相同的树:isSameRec, isSame
 * 9. 判断二叉树是不是平衡二叉树:isAVLRec
 * 10. 求二叉树的镜像(破坏和不破坏原来的树两种情况):mirrorRec, mirrorCopyRec
 * 10.1 判断两个树是否互相镜像:isMirrorRec
 * 11. 求二叉树中两个节点的最低公共祖先节点:getLastCommonParent, getLastCommonParentRec, getLastCommonParentRec2
 * 12. 求二叉树中节点的最大距离:getMaxDistanceRec
 * 13. 由前序遍历序列和中序遍历序列重建二叉树:rebuildBinaryTreeRec
 * 14.判断二叉树是不是完全二叉树:isCompleteBinaryTree, isCompleteBinaryTreeRec
 * 
 */
public class Demo {

	/*
	 			 1 
		        / \ 
		       2   3 
		      / \   \ 
		     4  5   6 
	 */
	public static void main(String[] args) {
		TreeNode r1 = new TreeNode(1);
		TreeNode r2 = new TreeNode(2);
		TreeNode r3 = new TreeNode(3);
		TreeNode r4 = new TreeNode(4);
		TreeNode r5 = new TreeNode(5);
		TreeNode r6 = new TreeNode(6);
		
		r1.left = r2;
		r1.right = r3;
		r2.left = r4;
		r2.right = r5;
		r3.right = r6;
		
//		System.out.println(getNodeNumRec(r1));
//		System.out.println(getNodeNum(r1));
//		System.out.println(getDepthRec(r1));
//		System.out.println(getDepth(r1));
		
//		preorderTraversalRec(r1);
//		System.out.println();
//		preorderTraversal(r1);
//		System.out.println();
//		inorderTraversalRec(r1);
//		System.out.println();
//		inorderTraversal(r1);
//		System.out.println();
//		postorderTraversalRec(r1);
//		System.out.println();
//		postorderTraversal(r1);
//		System.out.println();
//		levelTraversal(r1);
//		System.out.println();
//		levelTraversalRec(r1);
//		System.out.println();
		
//		TreeNode tmp = convertBSTRec(r1);
//		while(true){
//			if(tmp == null){
//				break;
//			}
//			System.out.print(tmp.val + " ");
//			if(tmp.right == null){
//				break;
//			}
//			tmp = tmp.right;
//		}
//		System.out.println();
//		while(true){
//			if(tmp == null){
//				break;
//			}
//			System.out.print(tmp.val + " ");
//			if(tmp.left == null){
//				break;
//			}
//			tmp = tmp.left;
//		}
		
		
//		TreeNode tmp = convertBST2DLL(r1);
//		while(true){
//			if(tmp == null){
//				break;
//			}
//			System.out.print(tmp.val + " ");
//			if(tmp.right == null){
//				break;
//			}
//			tmp = tmp.right;
//		}
		
//		System.out.println(getNodeNumKthLevelRec(r1, 2));
//		System.out.println(getNodeNumKthLevel(r1, 2));
		
//		System.out.println(getNodeNumLeafRec(r1));
//		System.out.println(getNodeNumLeaf(r1));
		
//		System.out.println(isSame(r1, r1));
//		inorderTraversal(r1);
//		System.out.println();
//		mirror(r1);
//		TreeNode mirrorRoot = mirrorCopy(r1);
//		inorderTraversal(mirrorRoot);
		
		System.out.println(isCompleteBinaryTree(r1));
		System.out.println(isCompleteBinaryTreeRec(r1));
		
	}

	private static class TreeNode {
		int val;
		TreeNode left;
		TreeNode right;

		public TreeNode(int val) {
			this.val = val;
		}
	}

	/**
	 * 求二叉树中的节点个数递归解法: O(n)
	 * (1)如果二叉树为空,节点个数为0 
	 * (2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 +
	 *    	      右子树节点个数 + 1
	 */
	public static int getNodeNumRec(TreeNode root) {
		if (root == null) {
			return 0;
		} else {
			return getNodeNumRec(root.left) + getNodeNumRec(root.right) + 1;
		}
	}
	
	/**
	 *  求二叉树中的节点个数迭代解法O(n):基本思想同LevelOrderTraversal,
	 *  即用一个Queue,在Java里面可以用LinkedList来模拟 
	 */
	public static int getNodeNum(TreeNode root) {
		if(root == null){
			return 0;
		}
		int count = 1;
		Queue<TreeNode> queue = new LinkedList<TreeNode>();
		queue.add(root);
		
		while(!queue.isEmpty()){
			TreeNode cur = queue.remove();		// 从队头位置移除
			if(cur.left != null){			// 如果有左孩子,加到队尾
				queue.add(cur.left);
				count++;
			}
			if(cur.right != null){		// 如果有右孩子,加到队尾
				queue.add(cur.right);
				count++;
			}
		}
		
		return count;
	}

	/**
	 * 求二叉树的深度(高度) 递归解法: O(n)
	 * (1)如果二叉树为空,二叉树的深度为0 
	 * (2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1
	 */
	public static int getDepthRec(TreeNode root) {
		if (root == null) {
			return 0;
		}

		int leftDepth = getDepthRec(root.left);
		int rightDepth = getDepthRec(root.right);
		return Math.max(leftDepth, rightDepth) + 1;
	}
	
	/**
	 * 求二叉树的深度(高度) 迭代解法: O(n)
	 * 基本思想同LevelOrderTraversal,还是用一个Queue
	 */
	public static int getDepth(TreeNode root) {
		if(root == null){
			return
PyTorch复现EEG-TCNet踩坑记:从BCI IV2a数据到TCN块缺失的完整解决方案 本文详细解析了使用PyTorch复现EEG-TCNet模型的全过程,重点解决了BCI IV2a数据集预处理和TCN模块缺失的技术难题。通过标准化数据流程、跨受试者验证策略以及三种因果卷积实现方案,为运动想象分类任务提供完整解决方案,帮助研究者高效实现模型复现与优化。 阅读详情

相关推荐

win11重装系统简易教程-小白也可以上手!

本文介绍一下win11系统重装的各个步骤,也作为记录供自己后面查看。附上我之前参考的一位知乎大神写的重装win10系统文章的地址本文用到的工具全部是,不需要下载第三方镜像文件(不是说这个不好,只是第三方的软件或镜像文件网上非常多,琳琅满目,小白需要筛选甄别,直接用官方的就比较省心,大神请自便~)

Sddqa的博客 1万+

植物叶绿体基因组分析全攻略:从共线性到密码子偏好性

本文全面解析植物叶绿体基因组分析流程,从共线性分析到密码子偏好性研究。详细介绍了叶绿体基因组结构特征、测序数据获取与质量控制、基因组组装与注释方法,以及比较基因组学和进化分析技术。特别关注IR区边界变异分析和选择压力评估,为植物系统发育研究和物种鉴定提供实用指南。

weixin_28475533的博客 222

盘点军工行业软件研发的那些常用GJB标准

GJB5000、2786、438、141、102、8114等...

文章主要涉及嵌入式软件开发、测试、项目管理等,欢迎交流,共同进步。 9450

FMT(基于rtthread)开源代码编译 win10下编译环境搭建及编译

FMT(基于rtthread)开源代码编译 win10下编译环境搭建及编译 什么是Firmament? Firmament (FMT) 是一款基于模型设计 (Model-Based-Design, MBD) 的开源自驾仪,可被用来快速构建无人机,无人车,无人船,机器人等平台的控制系统。 系统主要由两部分构成. FMT-Firmware: 一个基于C/C++开发的稳定、高性能的嵌入式系统. FMT-Model: 一个基于MATLAB/Simulink开发的仿真框架以及算法库. 昨天得知FMT开源飞控项目已经开

weixin_45786595的博客 2873

计算机视觉——SIFT特征匹配

文章目录一、SIFT特征检测原理1.1基本思想1.2二、SIFT特征检测图片兴趣点三、SIFT特征检测描述子匹配四、输入图片检测与之 一、SIFT特征检测原理 1.1基本思想 1.2 二、SIFT特征检测图片兴趣点 代码: 检测结果: 三、SIFT特征检测描述子匹配 四、输入图片检测与之 ...

weixin_43869874的博客 3855

从412到200:一步步拆解瑞数6代jsvmp的cookie生成与验证流程

本文深入解析瑞数6代JSVMP的动态安全防护机制,详细拆解从412到200状态的cookie生成与验证流程。通过剖析JSVMP虚拟机核心机制、动态元数据解析及环境检测绕过策略,为逆向工程师提供实用的技术解决方案,帮助突破瑞数6代的高级防御体系。

weixin_30342209的博客 508

人工智能机器学习从入门到高级学习资料(含资料下载地址)

机器学习是一个技术含量较高的领域,高效学习需要多种途径相结合.以下是一些推荐的学习资源。首先介绍几个比较有用的社区,包含了丰富的学习资料

2401_86900375的博客 1648

OpenClaw 多机器人多 Agent 模式:打造你的 AI 助手团队

OpenClaw多Agent模式为企业提供高效的AI助手团队解决方案。通过创建4个独立的飞书机器人(主助理、内容创作、技术开发、AI资讯),每个连接专属Gateway和Agent模型(如Claude Opus/Sonnet、Gemini 2.5),实现专业分工。相比单Agent模式,多Gateway架构具有配置清晰、互不干扰、无需手动切换等优势。系统采用Profile隔离机制,各Agent拥有独立配置和端口。部署过程包括创建机器人应用、配置Agent、运行自动化脚本等步骤,支持私聊或群组@使用。日常提供状态

Maynor的博客 5100

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

上一篇: Flatten Binary Tree to Linked List 二叉树变成链表@LeetCode,
下一篇: Search in Rotated Sorted Array 旋转数组里查找数 @LeetCode
chiiis
博客等级 码龄14年 422粉丝 429原创
评论 24
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值