每日算法——对称二叉树
Posted 与你同在架构之路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日算法——对称二叉树相关的知识,希望对你有一定的参考价值。
大家好,我是宇哥
前言
最近一直在更新关于树的相关知识,然后就去leetcode上整个算法玩玩,万万没想到,还差大远。以后坚持每日一道算法题。第二天
题目:
给定一个二叉树,检查它是否是镜像对称的。
https://leetcode-cn.com/problems/symmetric-tree/
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
\
2 2
\ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
\
2 2
\ \
3 3
进阶:
你可以运用递归和迭代两种方法解决这个问题吗?
解题思路:
递归思想,
判断父节点为null 结束返回true
判断父节点的子,左节点和右节点为为null 并且相等返回true,否则 返回false
左节点的值和右节点的值不相等返回false,否则 继续递归左节点和右节点
终解AC代码:自己经过不懈尝试最终成功了,好的开始
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
// 空节点直接返回
if (root == null) return true;
return leftRight(root.left,root.right);
}
/**
* 递归调用
* left 左节点
* right 右节点
**/
private boolean leftRight(TreeNode left, TreeNode right) {
// 节点判null
if (left == null || right == null) return left == right;
// 对称节点值判断
if (left.val != right.val) return false;
//左节点的 左,右节点的 右 | 左节点的 右,右节点的 左
return leftRight(left.left,right.right) && leftRight(left.right,right.left);
}
}
复杂度分析
假设树上一共 n 个节点。
时间复杂度:这里遍历了这棵树,渐进时间复杂度为 O(n)。
空间复杂度:这里的空间复杂度和递归使用的栈空间有关,这里递归层数不超过 n,故渐进空间复杂度为 O(n)。
大佬们的解法和思路:
首先我们引入一个栈/队列,这是把递归程序改写成迭代程序的常用方法。初始化时我们把根节点入队两次。每次提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。
代码如下:
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
//构建一个栈
Stack<TreeNode> stack = new Stack<>();
//向里添加树左右节点
stack.push(root.left);
stack.push(root.right);
//栈不空就循环
while(!stack.empty()) {
//弹出栈里元素
TreeNode n1 = stack.pop();
TreeNode n2 = stack.pop();
//进行非空判断
if (n1 == null && n2 == null) continue;
//进行对称判断
if (n1 == null || n2 == null || n1.val != n2.val ) return false;
//向栈里添加子树叉,然后继续循环 n1(左)n2(右)
//顺序 左节点的 左,右节点的 右
stack.push(n1.left);
stack.push(n2.right);
//顺序 左节点的 右,右节点的 左
stack.push(n1.right);
stack.push(n2.left);
//添加元素之后就可以继续循环了
}
return true;
}
复杂度分析
时间复杂度:O(n)
空间复杂度:这里需要用一个队列来维护节点,每个节点最多进队一次,出队一次,队列中最多不会超过 n 个点,故渐进空间复杂度为 O(n)。
小结:
day2独立写出第一个算法题,虽然是简单题,但也很 nice。一步步来。