剑指offer:对称的二叉树(镜像,递归,非递归DFS栈+BFS队列)
1. 题目描述
/**
请实现一个函数,用来判断一颗二叉树是不是对称的。
注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的
*/
2. 递归
思路:
/**
1.只要pRoot.left和pRoot.right是否对称即可
2.左右节点的值相等且对称子树left.left, right.right; left.rigth,right.left也对称
*/
代码:
import java.util.*;
public class Solution {
boolean isSymmetrical(TreeNode pRoot){
if(pRoot == null) return true;
return isSymmetrical(pRoot.left, pRoot.right);
}
private boolean isSymmetrical(TreeNode left, TreeNode right) {
if(left == null && right == null) return true;
if(left == null || right == null) return false;
return left.val == right.val //为镜像的条件:左右节点值相等
&& isSymmetrical(left.left, right.right) //2.对称的子树也是镜像
&& isSymmetrical(left.right, right.left);
}
}
3. 非递归(深度遍历)
思路
/*
* DFS使用stack来保存成对的节点
* 1.出栈的时候也是成对的 ,
1.若都为空,继续;
2.一个为空,返回false;
3.不为空,比较当前值,值不等,返回false;
* 2.确定入栈顺序,每次入栈都是成对成对的,如left.left, right.right ;left.rigth,right.left
*/
代码
import java.util.*;
public class Solution {
boolean isSymmetrical(TreeNode pRoot){
return isSymmetricalDFS(pRoot);
}
boolean isSymmetricalDFS(TreeNode pRoot){
if(pRoot == null) return true;
Stack<TreeNode> s = new Stack<>();
s.push(pRoot.left);
s.push(pRoot.right);
while(!s.empty()) {
TreeNode right = s.pop();//成对取出
TreeNode left = s.pop();
if(left == null && right == null) continue;
if(left == null || right == null) return false;
if(left.val != right.val) return false;
//成对插入
s.push(left.left);
s.push(right.right);
s.push(left.right);
s.push(right.left);
}
return true;
}
}
4. 非递归(广度遍历)
思路:
/*
* BFS使用Queue来保存成对的节点,代码和上面极其相似
* 1.出队的时候也是成对成对的
1.若都为空,继续;
2.一个为空,返回false;
3.不为空,比较当前值,值不等,返回false;
* 2.确定入队顺序,每次入队都是成对成对的,如left.left, right.right ;left.rigth,right.left
*/
代码
import java.util.*;
public class Solution {
boolean isSymmetrical(TreeNode pRoot){
return isSymmetricalBFS(pRoot);
}
boolean isSymmetricalBFS(TreeNode pRoot)
{
if(pRoot == null) return true;
Queue<TreeNode> s = new LinkedList<>();
s.offer(pRoot.left);
s.offer(pRoot.right);
while(!s.isEmpty()) {
TreeNode left= s.poll();//成对取出
TreeNode right= s.poll();
if(left == null && right == null) continue;
if(left == null || right == null) return false;
if(left.val != right.val) return false;
//成对插入
s.offer(left.left);
s.offer(right.right);
s.offer(left.right);
s.offer(right.left);
}
return true;
}
}
剑指offer:对称的二叉树(镜像,递归,非递归DFS栈+BFS队列)的更多相关文章
- 剑指Offer——对称的二叉树
题目描述: 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 分析: 递归解法. 如果对称点一个有一边为空一边不为空,或者是对称点数值不一 ...
- python实现剑指offer对称的二叉树
题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. # -*- coding:utf-8 -*- # class TreeNode ...
- 《剑指offer》— JavaScript(5)用两个栈实现队列
用两个栈实现队列 题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 实现代码 function Stack(){ var item = []; this. ...
- (剑指Offer)面试题7:用两个栈实现队列
题目: 用两个栈实现一个队列. 队列的声明如下:请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能. 思路: 根据栈的“先进后出”特点, ...
- 剑指offer第二版面试题8:用两个栈实现队列(JAVA版)
题目:用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deletedHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能. 分析: 我们通过一个具体的例子来分析 ...
- 剑指offer——已知二叉树的先序和中序排列,重构二叉树
这是剑指offer中关于二叉树重构的一道题.题目原型为: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2, ...
- 《剑指offer》重建二叉树
本题来自<剑指offer> 重构二叉树 题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2 ...
- 剑指 Offer 68 - II. 二叉树的最近公共祖先 + 最近公共祖先(LCA)
剑指 Offer 68 - II. 二叉树的最近公共祖先 Offer_68_2 题目详情 题解分析 java代码 package com.walegarrett.offer; /** * @Autho ...
- 剑指 Offer 68 - II. 二叉树的最近公共祖先
剑指 Offer 68 - II. 二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近 ...
- 力扣 - 剑指 Offer 55 - I. 二叉树的深度
题目 剑指 Offer 55 - I. 二叉树的深度 思路1(DFS) 后续遍历吧,先遍历到最深(递归到末尾返回0),然后从后面一步一步比较取大的值返回,每次返回层数都加1, 执行流程是怎样的:比如其 ...
随机推荐
- Codeforces Round #603 (Div. 2) F. Economic Difficulties dp
F. Economic Difficulties An electrical grid in Berland palaces consists of 2 grids: main and reserve ...
- PHP实现Redis分布式锁
锁在我们的日常开发可谓用得比较多.通常用来解决资源并发的问题.特别是多机集群情况下,资源争抢的问题.但是,很多新手在锁的处理上常常会犯一些问题.今天我们来深入理解锁. 一.Redis 锁错误使用之一 ...
- python接口自动化9-ddt数据驱动
前言 ddt:数据驱动,说的简单一点,就是多组测试数据,比如点点点的时候登录输入正常.异常的数据进行登录. 实际项目中,自动化测试用得很少,但也有人用excel来维护测试数据 一.ddt 1.安装:p ...
- SVN基本使用
1.把服务器的所有内容下载到本地 svn checkout 服务器地址 --username=使用者 --password=密码 2.添加文件 touch main.m(文件名) : 创建main.m ...
- IT兄弟连 Java语法教程 注释与编码规范
在程序代码中适当地添加注释可以提高程序的可读性和可维护性.好的编码规范可以使程序更易阅读和理解.下面将介绍Java中的集中代码注释以及应该注意的编码规范. 代码注释 通过在程序代码中添加注释可提高程序 ...
- 【计算机网络】HTTPS协议的传输细节及过程分析
1. 介绍一下HTTPS协议? 1.1 基本概念 http默认采用80作为通讯端口,对于传输采用不加密的方式,https默认采用443,对于传输的数据进行加密传输. 1.2 密码学基础 明文: 明文指 ...
- laravel中视图的基本使用(七)
laravel中的视图默认保存在 resources\views 目录下.在控制器中,我们通常使用 view() 方法返回一个视图文件. <?php namespace App\Http\Con ...
- Docker第二弹之常用命令
Docker的常用命令 底层原理 Docker是如何工作的 Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问,守护进程从 ...
- HashMap框架源码深入解读,面试不用愁
在Java Collections Framework的体系中中,主要有两个重要的接口,一个是List.Set和Queue所属的Collection,还有一个就是Map接口了.在上一篇文章中介绍了Li ...
- JS中for,for...in,for...of以及foreach循环的用法
1.for()循环 // for循环的表达式之间用的是;号分隔的,千万不要写成, for (初始化表达式1; 判断表达式2; 自增表达式3) { // 循环体4 } 2.for...in索引遍历 va ...