【数据结构】二叉树:LeetCode题(三)28. 对称的二叉树,100. 相同的树

219 阅读1分钟

28. 对称的二叉树¹

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

例如,二叉树 [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

示例 1:

输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false

限制:

0 <= 节点个数 <= 1000

注意:本题与主站 101 题相同:leetcode-cn.com/problems/sy…

1.分治*

  • 思路:
    • 对称特征
    1. 根节点:为空时对称
    2. 第二级节点:必须相同
    3. 第 >= 三级节点:left.left = right.right && left.right = right.left
    • 分治:每个节点都对称,则总体对称
    1. 函数:boolean f (right, left)
    2. 结束条件:root = null
    3. 分解:s.val == t.val && isSymmetirc(s.left, t.right) && isSymmetirc(s.right, t.left)
    4. 合并:直接放回分解结果即可
// Time:O(n), Space:O(n)
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null) return true;
        return isSymmetric(root.left, root.right);
    }

    private boolean isSymmetric(TreeNode s, TreeNode t) {
        if (s != null && t != null) 
            return s.val == t.val && isSymmetric(s.left, t.right) && isSymmetric(s.right, t.left);
        else 
            return s == null && t == null;
    }
}

2.DFS(栈)

迭代借助栈实现更好理解一点

// Time:O(n), Space:O(n)
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.isEmpty()) {
            TreeNode r = stack.pop(), l = stack.pop();
            // 1.两个节点都为空,则当前节点对称
            if (r == null && l == null) continue;
            // 2.一个节点为空,部队称
            if (r == null || l == null) return false;
            // 3.两个节点都非空,判断这两个节点是否相同
            // 3.1 不同则不对称
            if (r.val != l.val) return false;
			
            // 3.2 相同,再按序入栈(这里的顺序必要一边left,一边right)
            stack.push(r.left);
            stack.push(l.right);
            stack.push(r.right);
            stack.push(l.left);
        }
        return true;
    }

100. 相同的树¹

给定两个二叉树,编写一个函数来检验它们是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:

输入:       1         1
          / \       / \
         2   3     2   3

        [1,2,3],   [1,2,3]

输出: true

示例 2:

输入:      1          1
          /           \
         2             2

        [1,2],     [1,null,2]

输出: false

示例 3:

输入:       1         1
          / \       / \
         2   1     1   2

        [1,2,1],   [1,1,2]

输出: false

1.分治*

public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) return true;
        if (p == null || q == null) return false;
        if (p.val != q.val) return false;
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }

2.DFS(栈)

同下面BFS,Queue换成stack即可

3.BFS

// 双队列,没必要
// Time:O(n), Space:O(n)
public boolean isSameTree(TreeNode p, TreeNode q) {
    	// 注意:这里的判断条件
        if (p == null && q == null) return true;
        if (p == null || q == null) return false;
        
        Queue<TreeNode> queueP = new LinkedList<>();
        Queue<TreeNode> queueQ = new LinkedList<>();
        queueP.offer(p);
        queueQ.offer(q);

        while (!queueP.isEmpty() || !queueQ.isEmpty()) {
            TreeNode p1 = queueP.poll();
            TreeNode q1 = queueQ.poll();
            // 1.两个都空
            if (p1 == null && q1 == null) continue;
            // 2.一个空
            if (p1 == null || q1 == null) return false;
            // 3.两个都不空
            if (p1.val != q1.val ) return false;
			
            // 注:这里的入队顺序:同一队中先左后右
            queueP.offer(p1.left);
            queueP.offer(p1.right);
            queueQ.offer(q1.left);
            queueQ.offer(q1.right);
        }

        return true;
    }
// Time:O(n), Space:O(n)
public boolean isSameTree(TreeNode p, TreeNode q) {
        
        if (p == null && q == null) return true;
        if (p == null || q == null) return false;
        
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(p);
        queue.offer(q);

        while (!queue.isEmpty()) {
            // 一次出两个节点就行了
            TreeNode p1 = queue.poll();
            TreeNode q1 = queue.poll();
            
            if (p1 == null && q1 == null) continue;
            if (p1 == null || q1 == null) return false;
            if (p1.val != q1.val ) return false;
			
            // 注:这里的入队顺序:先左后右
            queue.offer(p1.left);
            queue.offer(q1.left);
            queue.offer(p1.right);
            queue.offer(q1.right);
        }

        return true;
    }