面试大总结之二: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
Windows下CMake编译VTK 选择项目INSTALL,生成该项目,得到vtk在Debug模式下的lib和dll文件,在文件夹中可看见,已得到debug模式下lib库与dll库。,把Value值设置为最后在vtk_sln中生成include、dll、lib的位置。在上面点击Configure后,红色区域没有了。选择自己vs编译平台的版本信息,我这边已经设置好了没有这个设置了,借用参考博客的图片。设置完后,点击左下角"Configure",然后等待Configure。,把搜索结果的Value勾选上。在search中搜索。 阅读详情

相关推荐

Python+Flask+Echarts打造全国气象数据可视化分析大屏

本文详细介绍了如何使用Python+Flask+Echarts构建全国气象数据可视化分析大屏,实现实时监控、趋势分析和快速决策。通过Python强大的数据处理能力、Flask的轻量级优势和Echarts的交互体验,打造高效的气象数据可视化系统,提升农业、物流等行业的决策效率。

weixin_29061531的博客 1060

1G/2.5G Ethernet PCS/PMA or SGMII

SGMII即Serial GMII,串行GMII,收发各一对差分信号线,时钟频率625MHz,在时钟信号的上升沿和下降沿均采样,所以总的数据速率为1.25Gbps=625Mbps*2。参考时钟RX_CLK由PHY提供,是可选的,主要用于MAC侧没有时钟的情况,一般情况下,RX_CLK不使用。收发都可以从数据中恢复出时钟。在TXD发送的串行数据中,每8比特数据会插入TX_EN/TX_ER 两比特控制信息,同样,在RXD接收数据中,每8比特数据会插入RX_DV/RX_ER 两比特控制信息。

sqzjiayou的博客 1万+

别再只看成交量了!用通达信这个VOL监测公式,一眼识别主力吸筹与出货信号

本文详细介绍了通达信VOL监测公式的实战应用,通过彩色量柱和换手率分层技术,帮助投资者识别主力吸筹与出货信号。该公式结合动态量能标准化和多周期均线组合,提供可视化主力行为图谱,提升交易决策的准确性。

weixin_28693447的博客 662

ESP32-IDF HTTP服务器实战:从零搭建Web控制界面

本文详细介绍了如何在ESP32平台上使用ESP-IDF框架从零搭建HTTP服务器,并创建Web控制界面。内容涵盖环境配置、服务器基础设置、Web页面处理、GPIO控制接口实现及AJAX异步请求处理,帮助开发者快速掌握物联网设备Web控制开发。

efc123456的博客 1063

图神经网络在金融风险传播分析中的应用

《图神经网络在金融风险传播分析中的应用》 摘要 本文旨在探讨图神经网络(Graph Neural Networks, GNN)在金融风险传播分析中的应用。首先,本文简要介绍了图神经网络的基本概念、发展历史以及其在各类应用场景中的重要性。接着,详细介绍了图神经网络的核心算法,包括图卷积神经网

AI天才研究院 1280

【Frida Android】实战篇4:SSL Pinning 证书绑定绕过 Hook 教程(一)

在前两章中,我们学习了中间人抓包与 Hook 抓包的基础方法,这些方法在理想环境下能够有效获取网络请求数据。但在实际的企业级应用中,出于安全防护需求,很多 APP 会启用证书绑定(SSL Pinning)机制。这种机制会让客户端对服务器证书的校验更为严格,导致常规的抓包方法(即使将 BurpSuite/Charles 证书安装到系统信任区)也无法生效。因此,从本章开始,我们将系统学习 SSL Pinning 机制的绕过技术。SSL Pinning(证书绑定)是客户端校验服务器身份的进阶安全机制。

水滴石穿 1611

FineReport实战-- 国内外各地区销售数据分析 多个图表联动

进行国内外各地区业务员销售数据分析是一项复杂但极具价值的任务,它可以帮助企业了解不同市场的表现,并据此调整销售策略以提高整体绩效。实现功能:同一个报表里面多个图表联动问题。

Davina_yu的博客 1200

(第78天)DB RU 补丁升级:19C 升级到 19.22

目前 Oracle 19C 是最新的稳定支持的版本,生产环境中使用的越来越多。当然,随着客户使用量的增多,自然无可避免的产生了很多 BUG,Oracle 每季度都会发布一个 RU 补丁来修复当前季度所产生的一些重要 BUG 补丁。作为 DBA,DB 补丁修复必然是需要掌握的一项技能。本文将介绍如何将数据库升级到最新的 RU 版本。

LuciferLiu_DBA 845

Statistics and Machine Learning Toolbox

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

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: 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、付费专栏及课程。

余额充值