zoukankan      html  css  js  c++  java
  • leetcode 572. Subtree of Another Tree

    Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself.

    Example 1:
    Given tree s:

         3
        / 
       4   5
      / 
     1   2
    

    Given tree t:

       4 
      / 
     1   2
    

    Return true, because t has the same structure and node values with a subtree of s.

    Example 2:
    Given tree s:

         3
        / 
       4   5
      / 
     1   2
        /
       0
    

    Given tree t:

       4
      / 
     1   2
    

    Return false.

    解法1:

    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def isSubtree(self, s, t):
            """
            :type s: TreeNode
            :type t: TreeNode
            :rtype: bool
            """
            def same(s, t):
                if s is None or t is None:
                    return s == t
                else:
                    return s.val == t.val and same(s.left, t.left) and same(s.right, t.right)
            if s is None:
                return t is None
            return same(s, t) or self.isSubtree(s.left, t) or self.isSubtree(s.right, t)
    

    解法2:

    先遍历树,生成字符串,然后利用字符串查找思路做。不喜欢这种解法,因为字符串查找时间复杂度最坏也是O(nm)。

    解法3:

    类似simhash或者Merkle 树——空间换时间,分而治之的hash表,通过根节点是由它的两个子节点内容的哈希值组成来校验数据完整性,定位篡改的数据位置算法,每一个节点自下而上计算其hash,然后比较hash是否相等即可判定是否有相同子树。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        boolean hasSub = false;
        public boolean isSubtree(TreeNode s, TreeNode t) {
            if (s == null) return t == null;
            hashAndCompare(s, t, hashAndCompare(t, null, 0));
            return hasSub;
        }
        
        private int hashAndCompare(TreeNode s, TreeNode t, int tHash) {
            if (s == null) return 0;
            int myHash = hashAndCompare(s.left, t, tHash) + hashAndCompare(s.right, t, tHash) + (s.val == 0? 1337 : s.val) * 401;
            if (myHash == tHash && !hasSub) hasSub = equals(s, t);
            return myHash;
        }
        
        private boolean equals(TreeNode s, TreeNode t) {
            if (s == null || t == null) return s == t;
            if (s.val != t.val) return false;
            return equals(s.left, t.left) && equals(s.right, t.right);
        }
    }
    

    我自己的解法:

    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def isSubtree(self, s, t):
            """
            :type s: TreeNode
            :type t: TreeNode
            :rtype: bool
            """        
            ans = False
            
            def same_tree(t1, t2):
                if t1 is None or t2 is None:
                    return t1 == t2
                return t1.val == t2.val and same_tree(t1.left, t2.left) and same_tree(t1.right, t2.right)
                
            def hash_node(node, hash_t):
                if not node:                
                    return 0
                l = hash_node(node.left, hash_t)            
                r = hash_node(node.right, hash_t)
                h = hash(str(l+r+node.val))
                nonlocal ans
                if h == hash_t and not ans:                
                    ans = same_tree(node, t) 
                return h
            
            hash_t = hash_node(t, None)    
            hash_node(s, hash_t)
            return ans
        
    
  • 相关阅读:
    【PC Basic】CPU、核、多线程的那些事儿
    为什么要使用 do while(0)?
    DPDK CAS(compare and set)操作
    编程中Foo,Bar 到底是什么意思
    如何用Python进行ARP攻击?
    有哪些有趣的化学方程式?
    1636. 按照频率将数组升序排序
    1046. 最后一块石头的重量
    1122. 数组的相对排序
    459. 重复的子字符串
  • 原文地址:https://www.cnblogs.com/bonelee/p/9074774.html
Copyright © 2011-2022 走看看