Find Duplicate Subtrees - Leetcode 652 - Python

Sdílet
Vložit
  • čas přidán 25. 07. 2024
  • 🚀 neetcode.io/ - A better way to prepare for Coding Interviews
    🥷 Discord: / discord
    🐦 Twitter: / neetcode1
    🐮 Support the channel: / neetcode
    ⭐ BLIND-75 PLAYLIST: • Two Sum - Leetcode 1 -...
    💡 DYNAMIC PROGRAMMING PLAYLIST: • House Robber - Leetco...
    Problem Link: leetcode.com/problems/find-du...
    0:00 - Read the problem
    2:05 - Drawing Explanation
    9:30 - Coding Explanation
    leetcode 652
    #neetcode #leetcode #python

Komentáře • 45

  • @NeetCodeIO
    @NeetCodeIO  Před rokem +53

    I'll be traveling next week, so unfortunately I won't be able to do the daily problems for about 7 days. Will continue them as soon as I get back tho! 🚀

    • @vixguy
      @vixguy Před rokem

      Enjoy your travels!!

    • @shashankreddy4620
      @shashankreddy4620 Před rokem

      this question can be done in O(n) time complexity
      we are storing strings so it will take O(n2) time

  • @tunguyenxuan8296
    @tunguyenxuan8296 Před rokem +28

    One leetcode a day, keeps unemployment away. Thanks for the content.

  • @uptwist2260
    @uptwist2260 Před rokem +17

    your explanations keep getting better. thanks for the daily

    • @ferb7o2
      @ferb7o2 Před rokem +4

      dude is in another level

  • @gaurangjotwani11
    @gaurangjotwani11 Před rokem +4

    You have the best explanations on entire CZcams! Will miss you for next week :(

  • @yang5843
    @yang5843 Před rokem +5

    Thanks Neetcode, you earned me the February Badge for this month's Leetcode.

  • @puneetkumarsingh1484
    @puneetkumarsingh1484 Před rokem +1

    Thanks for the mind blowing solution. For me the key observation was the fact that adding the null value while serializing the Tree makes the resultant string unique to the tree itself which generally is not the case with only preorder, postorder or inorder traversal.

  • @akshatsinghbodh3067
    @akshatsinghbodh3067 Před rokem

    Thank you for starting this series!

  • @anishkarthik4309
    @anishkarthik4309 Před rokem

    your videos literally have the best explanations. love your videos and keep on doing it. Have a great trip.

  • @sanjeevrajora7335
    @sanjeevrajora7335 Před rokem +1

    concept of serialising the tree into string and storing it to hash map is a real hack, keep up the good job

  • @ancai5498
    @ancai5498 Před 6 měsíci

    Thanks, Neet for the clear solution, two major points here:
    1. Time complexity, O(n^2), we need to visit each node, and the maximum length for hashing the string would be O(n) so overall is n * O(n);
    2. The way this question asks has some issues, basically, we should only return sets of duplicate trees which does the map[key].size() == 1 come from. For eg, using the example in the video, node 4 itself is duplicated and should return {{2, 4}, {4}, {4}} if we don't add that check.

  • @vixguy
    @vixguy Před rokem

    Very nice! I came up with the same idea but had some trouble implementing it

  • @madhavdua8588
    @madhavdua8588 Před rokem

    Thank you so much sir. Keep helping us by posting such content.

  • @krateskim4169
    @krateskim4169 Před rokem

    Awesome solution

  • @keremt8727
    @keremt8727 Před rokem +2

    Hi, I think "subtrees" could just be a `set` of strings (we do not need a key-value pair in this question).

  • @suchandranath1273
    @suchandranath1273 Před rokem +2

    @neetcode Great explaination, I followed the same logic , but instead of adding the node to the defualt dict i just maintained the count, it ran a bit faster and saves huge memory. I directly saved the node to the res.
    attaching my code:
    class Solution:
    def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]:
    subtrees=defaultdict(int)
    def serialize(root):
    if root==None:
    return 'N'
    else:
    res=str(root.val)+","+serialize(root.left)+","+serialize(root.right)
    subtrees[res]+=1
    if subtrees[res]==2:
    ans.append(root)
    return res
    res=''
    ans=[]
    serialize(root)
    return ans

    • @infernoo365
      @infernoo365 Před rokem

      why did you use if subtrees[res]==2 ? defaultdict(int) returns 0 as default value

    • @infernoo365
      @infernoo365 Před rokem

      i think it's because you have added subtrees[res]+=1 before if condition, if you write after if the condition becomes ==1

    • @suchandranath1273
      @suchandranath1273 Před rokem +1

      @@infernoo365 Yes, I felt it clear if I write it this way. that was a bit confusing.

  • @xofjo6239
    @xofjo6239 Před rokem

    This question is poorly described in leetcode. However, Neetcode explained it very well. Thank you!

  • @tanish5662
    @tanish5662 Před rokem +2

    So as we are doing serialization and storing it a hashmap, we are having O(n) time complexity for lookup. Correct me if I am wrong.

  • @shubhampathak7926
    @shubhampathak7926 Před rokem +1

    A small suggestion: you can put the difficulty of the problems on thumbnail!
    Thanks for the content btw.

  • @soumodiptajana9001
    @soumodiptajana9001 Před 4 měsíci

    Awesome ❤

  • @oliverheber599
    @oliverheber599 Před rokem

    Why do we need to return s from the dfs function? It's not working when I don't return it, but I can't see why it's important?

  • @PulkitMalhotra
    @PulkitMalhotra Před 11 měsíci

    Nice problem

  • @shawnzhang3736
    @shawnzhang3736 Před 10 měsíci +2

    inorder failed at [0,0,0,0,null,null,0,null,null,null,0]. Only pre and post work.

  • @Walid-Sahab
    @Walid-Sahab Před rokem

    can anyone please explain me what line # 17 is doing ?

  • @sathwikmadhula9527
    @sathwikmadhula9527 Před rokem

    I have a doubt? Why are we using strings. Would lists not work?

  • @vaishnavip4808
    @vaishnavip4808 Před rokem

    I just had one small doubt.How are we really sure that the serialisation gives a unique subtree configuration.If the tree is not a BST, we need atleast one of preorder and postorder and an inorder to uniquely construct a tree.So just curious does this always work.And for inorder case, it might give 2 symmetric trees as equal even if they are not right?

    • @SarveshRansubhe
      @SarveshRansubhe Před rokem

      Thats y he said we should add null values.

    • @jazzyx95
      @jazzyx95 Před rokem

      @@SarveshRansubhe Adding 'null' still fails with InOrder, post and preorder works. To see why InOrder fails, see Alone Beast's comments.

  • @AllMightGaming-AMG
    @AllMightGaming-AMG Před rokem

    Using a tuple instead of a string is more efficient

  • @alonebeast5310
    @alonebeast5310 Před rokem +2

    The Inorder traversal wont work for this example:
    [0,0,0,0,null,null,0,null,null,null,0]
    0
    node1-> 0 0
    0 0

    • @jazzyx95
      @jazzyx95 Před rokem

      Good comment bro, I got stuck on the same test case with in-order. Your comment helped me figure out the issue!

    • @Pinzauti
      @Pinzauti Před rokem

      Same problem, I don't understand why though

  • @irfanalahi380
    @irfanalahi380 Před rokem

    Though it is explained here, I am still not sure why the runtime is O(n^2). The DFS is touching all nodes only once and the string is being generated one step at a time. Wha am I missing?

    • @m.kamalali
      @m.kamalali Před rokem +1

      Dic needs to compute the hash for key which is not simple here
      We need to get all nodes connected of this sub tree thats why we need n for hash
      So all time n for hash times n for dfs

  • @aerialbaz3802
    @aerialbaz3802 Před rokem

    I have replaced string representation with hashes and I think I have reduced TC and SC to linear. Tell me what I am doing wrong?
    Approach is to Use sha1 hash string representation to keep track of subtree. Since string representation can grow the size of tree, while sha1 hash string will be fixed length always.
    from hashlib import sha1
    class Solution:
    def dfs(self, root) -> str:
    if not root:
    return "Null"
    else:
    left_hash = self.dfs(root.left)
    right_hash = self.dfs(root.right)
    res = left_hash + right_hash
    res += str(root.val)
    if res in self.hashes and res not in self.result_hashes:
    self.result_hashes.add(res)
    self.results.append(root)
    else:
    self.hashes.add(res)
    return sha1(res.encode('utf-8')).hexdigest()
    def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]:
    self.hashes = set()
    self.result_hashes = set()
    self.results = []
    self.dfs(root)
    return self.results

  • @sathwikmadhula9527
    @sathwikmadhula9527 Před rokem

    Why hashing takes O(n) time complexity?

  • @mohamedsalama2743
    @mohamedsalama2743 Před 3 měsíci

    i thinks this postorder traversal not preorder

  • @jaadui_chirag
    @jaadui_chirag Před rokem

    Did not work for [2,1,11,11,null,1]

  • @ahmadbodayr7203
    @ahmadbodayr7203 Před 11 měsíci

    Bad test cases one of the two others namely inorder or postorder also works and the other doesnt which is wrong both of inorder and postorder shouldnt work as only preorder can give a unique tree string representation google the proof.