leetcode 101. Symmetric Tree 递归和迭代 python3

一.问题描述

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

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

    1
   / \
  2   2
 / \ / \
3  4 4  3

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

    1
   / \
  2   2
   \   \
   3    3

Note:
Bonus points if you could solve it both recursively and iteratively.

二.解题思路

这种题目基本都是有递归和迭代两种方法的,同时一般来首。。。递归一般都比迭代容易不少。。

先讲思路吧,首先知道啥是对称数,就是沿着root,把右子树来个180度翻转,发现和左子树一样,就是对称树。

因为你要对比两边子树的情况,所以你肯定得同时处理两个子树(或者说两个节点)。

要解决这个问题,首先是得定位到底是左边哪个node和右边哪个node比。

看图很容易知道:

假设当前的左node为left,右node为right,这两个节点是要对比的对称节点。

那么下一个你要对比的组就是 left.left == right.right 和 left.right==right.left。知道了这个就谈具体实现吧。

1.递归:

我们知道我们需要两个点left 和 right 来比较,因此递归接受两个参数,left 和 right 为当次需要对比的两个点,返回值为以它们俩为根的子树在整个树来看是不是对称的。

left和right传进来有几种情况:

<1. left和right都为None,说明到了叶子节点,是递归的结束,返回True

<2. left和right某一个为None,另外一个不为None, 剪枝操作,不管它们俩的子树如何,都不可能是对称的了。

<3. left和right都不为空并且它们俩值相等,检测它们的子树. 递归 isSymmetric(left.right,right.left) and isSymmetric(left.left, right.right)。

2.迭代

说实话这种题目完全就是适合递归,非要用迭代只能说,来吧。

其实思路和之前都一样,就是要用堆栈来存,因为要同时对比两个节点,所以用俩堆栈,一个存左子树一个存右子树,然后这俩个堆栈入栈顺序要相反。一个要先入左再入右,另一个先入右再入左(和我们上面说的一样),这样子出栈对比的就是正确的对比对象。

其他的一些细节其实和递归要注意的地方差不多。

也可以用一个栈来解决,每次就得弹出两个出来。然后存4个,顺序就要注意一下,要对比的两个得连续入栈。不过上面的好理解一点。

PS:当root为空时这个树竟然是对称的,我是佛了。

更多leetcode算法题解法: 专栏 leetcode算法从零到结束

给出三种实现。

三.源码

1.递归

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        def isSymmetricHelper(left,right):
            if not left and not right:return True
            if not right or not left:return False
            if left.val!=right.val:return False
            return isSymmetricHelper(left.left,right.right) and \
        isSymmetricHelper(left.right,right.left)
        if not root:return True
        return isSymmetricHelper(root.left,root.right)

2.迭代,双栈

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        if not root:return True
        left,right=[root.left],[root.right]
        res=True
        while left and right:
            node1,node2=left.pop(),right.pop()
            if not node1 and node2 or node1 and not node2:
                res=False
                break
            if node1 and node2:
                if node1.val==node2.val:
                    left.append(node1.left)
                    left.append(node1.right)
                    right.append(node2.right)
                    right.append(node2.left)
                else:
                    res=False
                    break
        return len(left)==len(right) and res

3.迭代,单栈

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        if not root:return True
        stack=[root.left,root.right]
        res=True
        while stack:
            node1,node2=stack.pop(),stack.pop()
            if not node1 and node2 or node1 and not node2:
                res=False
                break
            if node1 and node2:
                if node1.val==node2.val:
                    stack.append(node1.left)
                    stack.append(node2.right)
                    stack.append(node1.right)
                    stack.append(node2.left)
                else:
                    res=False
                    break
        return res

PS:像迭代的时候 res=False break这里其实可以直接返回 return False,然后把最后的return去掉,但是我觉得最好还是不要这样,因为很多时候我们一下子没考虑到所有情况,可能会导致函数没返回,特别是在递归的时候,导致的问题会很可怕。

发布了218 篇原创文章 · 获赞 191 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/CSerwangjun/article/details/103286240
今日推荐