zoukankan      html  css  js  c++  java
  • [LeetCode] 101. Symmetric Tree(对称的树)

    Description

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

    给一棵二叉树,判断它是否是自身的镜像(也就是关于 root 轴对称)

    For example, this binary tree [1, 2, 2, 3, 4, 4, 3] is symmetric:

    例如,二叉树 [1, 2, 2, 3, 4, 4, 3] 是对称的:

        1
       / 
      2   2
     /  / 
    3  4 4  3
    

    But the following [1, 2, 2, null, 3, null, 3] is not:

    但二叉树 [1, 2, 2, null, 3, null, 3] 不是:

        1
       / 
      2   2
          
       3    3
    

    Follow up

    Solve it both recursively and iteratively.

    以迭代和递归两种方法解决。

    Solution

    迭代解法:层序遍历

    如果一棵二叉树是左右对称的,那么其每一层节点的排布也应该是左右对称的。可以通过层序遍历找出每一层的所有节点,再检查这个节点列表是不是对称的。需要注意的是,层序遍历的时候,null 节点也是需要被考虑进去的,这样当树的层级过深时会有 MLE 的风险(特别是层级很深的稀疏树,一层下来大部分节点都是 null,占据无意义的空间。实际上我第一次提交就爆了内存)。问题出在层序遍历时往下扩张的过程,如果一个节点本身为 null,那就没有必要继续往下扩展了,这样可以节约大量内存,代码如下:

    /**
     * Example:
     * var ti = TreeNode(5)
     * var v = ti.`val`
     * Definition for a binary tree node.
     * class TreeNode(var `val`: Int) {
     *     var left: TreeNode? = null
     *     var right: TreeNode? = null
     * }
     */
    import java.util.*
    
    class Solution {
        fun isSymmetric(root: TreeNode?): Boolean {
            if (root == null) {
                return true
            }
            val queue: Queue<TreeNode?> = LinkedList()
            queue.offer(root)
    
            while (queue.isNotEmpty()) {
                val size = queue.size
                val values = arrayListOf<Int?>()
    
                for (i in 1..size) {
                    val node = queue.poll()
                    values.add(node?.`val`)
                    // 只对非 null 的节点进行扩展
                    node?.let {
                        queue.offer(it.left)
                        queue.offer(it.right)
                    }
                }
    
                if (values.all { it == null }) {
                    break
                }
    
                if (!values.isSymmetric()) {
                    return false
                }
            }
    
            return true
        }
    
        private fun List<Int?>.isSymmetric(): Boolean {
            if (this.size < 2) {
                return true
            }
            var left = 0
            var right = this.lastIndex
            while (left < right) {
                if (this[left] != this[right]) {
                    return false
                }
                left++
                right--
            }
            return true
        }
    }
    

    递归解法(来自 discussion):

    判断一个树是否镜像,则需要判断其左右子树是否能够通过翻转变化相等。这样就有和比较两棵树是否相等类似了,只不过递归调用的过程中,我们判断的是 left.rightright.left 以及 left.leftright.right 这两组是否相等,代码如下:

    /**
     * Example:
     * var ti = TreeNode(5)
     * var v = ti.`val`
     * Definition for a binary tree node.
     * class TreeNode(var `val`: Int) {
     *     var left: TreeNode? = null
     *     var right: TreeNode? = null
     * }
     */
    class Solution {
        fun isSymmetric(root: TreeNode?): Boolean {
            return root == null || isSymmetric(root.left, root.right)
        }
    
        private fun isSymmetric(left: TreeNode?, right: TreeNode?): Boolean {
            if (left == null || right == null) {
                return left == right
            }
            if (left.`val` != right.`val`) {
                return false
            }
            return isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left)
        }
    }
    
  • 相关阅读:
    MongoDB 3.0安全权限访问控制(Windows版)
    MVC创建通用DropdownList
    当文字超出宽度,自动截取文字并加省略号
    JQuery Datatables(二)
    JQuery Datatables(一)
    PHP signal 信号
    phpunit 入门
    Wget 命令详解
    ubuntn下 apt的用法和yum的比较(转)
    navicat for mysql 安装
  • 原文地址:https://www.cnblogs.com/zhongju/p/13825219.html
Copyright © 2011-2022 走看看