# 1530. Number of Good Leaf Nodes Pairs ```python= # Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right """ 1 2 3 4 5 6 depths_of_all_child_leaves(node_4) is [0] depths_of_all_child_leaves(node_5) is [0] depths_of_all_child_leaves(node_2) is [1, 1] named as A A_1 is [1+1, 1+1] depths_of_all_child_leaves(node_6) is [0] depths_of_all_child_leaves(node_3) is [1] named as B B_1 is [1+1] depths_of_all_child_leaves(node_1) is A_1 + B_1 """ class Solution: def countPairs(self, root: TreeNode, distance: int) -> int: self.good_pairs = 0 # be global to all dfs function-calls def depths_of_all_child_leaves(node): """Return a list of depths of all its child-leaves, could be itself.""" if not node: return [] if not node.left and not node.right: # termination return [0] left_depths = depths_of_all_child_leaves(node.left) right_depths = depths_of_all_child_leaves(node.right) left_depths_add_1 = [x + 1 for x in left_depths] right_depths_add_1 = [x + 1 for x in right_depths] # all lengths between: left-child leaves and right-child leaves # and pass this `node`; these will be shortest len_shortest_paths_thru_me = [ x + y for x in left_depths_add_1 for y in right_depths_add_1] self.good_pairs += sum(length <= distance for length in len_shortest_paths_thru_me) return left_depths_add_1 + right_depths_add_1 depths_of_all_child_leaves(root) # time: O(N^3); N is num of nodes return self.good_pairs class Solution: def countPairs(self, root: TreeNode, distance: int) -> int: self.good_pairs = 0 # be global to all dfs function-calls def depths_of_all_child_leaves(node): """Return a list of depths of all its child-leaves, could be itself.""" if not node: return [] if not node.left and not node.right: # termination return [0] left_depths = depths_of_all_child_leaves(node.left) right_depths = depths_of_all_child_leaves(node.right) left_depths_add_1 = [x + 1 for x in left_depths] right_depths_add_1 = [x + 1 for x in right_depths] # all lengths between: left-child leaves and right-child leaves # and pass this `node`; these will be shortest len_shortest_paths_thru_me = [ x + y for x in left_depths_add_1 for y in right_depths_add_1] self.good_pairs += sum(length <= distance for length in len_shortest_paths_thru_me) # remove those already too large; just for optimization return [x for x in left_depths_add_1 + right_depths_add_1 if x <= distance] depths_of_all_child_leaves(root) # time: O(N * 2^distance * 2^distance) return self.good_pairs class Solution: def countPairs(self, root: TreeNode, distance: int) -> int: """ Use counter instead of all literal int. """ self.good_pairs = 0 # be global to all dfs function-calls def depths_of_all_child_leaves(node): """Return a counter for depths of all its child-leaves, could be itself.""" counter = [0] * (distance + 1) # handmade counter for 0 ~ distance if not node: return counter if not node.left and not node.right: # termination counter[0] = 1 return counter left_depths = depths_of_all_child_leaves(node.left) right_depths = depths_of_all_child_leaves(node.right) # everyone plus 1, so counter if shifted; left_depths[1::] = left_depths[0:-1] right_depths[1::] = right_depths[0:-1] left_depths[0] = 0 right_depths[0] = 0 # If you want to use for-loop, # note that we have to update from the rear; # otherwise, li[0] will overwrite every slot # all lengths between: left-child leaves and right-child leaves # and pass this `node`; these will be shortest for x, ct_x in enumerate(left_depths): for y, ct_y in enumerate(right_depths): if x + y <= distance: self.good_pairs += ct_x * ct_y # combine return [x + y for x, y in zip(left_depths, right_depths)] depths_of_all_child_leaves(root) # time: O(N * distance^2) return self.good_pairs ```