How to break this down in simple steps(91%Time)!
Intuition\n Describe your first thoughts on how to solve this problem. \nEdges dict for faster access.\n\nMax dist can get caclulated via two bfs searches!\n\nL
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\nEdges dict for faster access.\n\nMax dist can get caclulated via two bfs searches!\n\nLast use recursion to shrink graph and get max dist for all smaller subgraphs also.\n\nReturn counter over different max dists found.\n# Code\n```\nclass Solution:\n    def countSubgraphsForEachDiameter(self, n: int, edges: List[List[int]]) -> List[int]:\n        edges2 = defaultdict(list) #direct access node edges in O(1) instead of traversing all edges\n        for a,b in edges:\n            edges2[a].append(b)\n            edges2[b].append(a)\n\n        def bfs(root,nodes): #bfs returning max depth and first node on last layer\n            level = [root] #bfs-queue\n            seen = {root} #dont use again flags\n            d = 0 #depth\n            while True: #do while\n                nextLevel = []\n                for node in level: #bfs\n                    for other in edges2[node]: #children\n                        if nodes[other-1]==True and other not in seen: #children not deleted or used already\n                            seen.add(other) #mark as used\n                            nextLevel.append(other) #add to next bfs queue\n                if nextLevel: #continue\n                    d += 1 #next depth reached\n                    level = nextLevel #take over children as bfs queue/layer\n                else: break #done with bfs\n            return level[0],d #first node + depth from root\n\n        seen = set() #dont reuse same combinations\n        def rec(nodes=[True for _ in range(n)]): #what dist is left with given connected nodes\n            seen.add(str(nodes)) #never eval this combination again\n            if sum(nodes)==1: return #deleted to much\n            for i,b in enumerate(nodes):\n                if b==True: #pick first node left as root\n                    root = i+1\n                    break\n            #double bfs=>max-depth-node yiels max dist\n            #also we have both reached nodes and the path between has the distance!\n            other,_ = bfs(root,nodes) #first bfs\n            _,dist = bfs(other,nodes) #second bfs\n            res[dist-1] += 1 #save another subtree got this dist\n\n            for i,b in enumerate(nodes): #try to delete nodes\n                if b==True: #this one is left\n                    node = i+1 #the node value 1-indexed\n                    reaches = 0 #counter\n                    for other in edges2[node]: #connected nodes\n                        if nodes[other-1]==True: #is not yet deleted\n                            reaches += 1 #add as connected node\n                    #leafs can get deleted!\n                    if reaches==1: #leafs have exactly 1 connection\n                        new = list(nodes) #unlinked copy for more readable recursion\n                        new[node-1] = False #flip deletable => smaller nodes combination\n                        if str(new) not in seen: #this combination is new!\n                            rec(new) #get max dist for subset also\n\n\n        res = [0 for _ in range(1,n)] #counts of max dists from 1 to n-1\n        rec() #recursivley use all subtrees\n        return res #return counts\n        \n```\n\n# Complexity\n- Time complexity:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\nEach max dist calculation uses O(n) and traverses the graph twice.\nThis happens inside the memoized valid node combinations and will be called n(n+1)/2 => O(n\xB2) times.\nThus we reach O(n\xB3) in summary.\n\n- Space complexity:\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\nO(n\xB2) memo dominates bfs space.\n\n
['Breadth-First Search', 'Recursion', 'Memoization', 'Python3']