if node.right and node.right.val == self.x: self.counts[2] = self.n - nr # if 1st player choose this parent node, by taking left/right child, how many blocked? if node.val == self.x: self.counts[:2] = (nr, nl) return nr + nl + 1 def btreeGameWinningMove(self, root: TreeNode, n: int, x: int) -> bool: # choose between (nodeX-left-child, nodeX-right-child, nodeX-parent), count and determine self.counts, self.n, self.x = [0, 0, 0], n, x self.recursive(root) return max(self.counts) > n // 2 if __name__ == '__main__': solver = Solution() cases = [ ([1, None, 2, 3], 3, 1), ([1, None, 2, 3], 3, 2), ([1, None, 2, 3], 3, 3), ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 11, 1), ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 11, 2), ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 11, 3), ] cases = [(listToTreeNode(r), n, x) for r, n, x in cases] rslts = [solver.btreeGameWinningMove(root, n, x) for root, n, x in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs else None} + {cs[1:]} | solution: {rs}" )
for x in dl: for y in dr: if x + y <= self.z: self.count += dl[x] * dr[y] d = defaultdict(lambda: 0) for x in dl: if x + 1 < self.z: d[x + 1] += dl[x] for x in dr: if x + 1 < self.z: d[x + 1] += dr[x] return d def countPairs(self, root: TreeNode, distance: int) -> int: self.count, self.z = 0, distance self.recursive(root) return self.count if __name__ == '__main__': solver = Solution() cases = [ ([1, 2, 3, 4, 5], 3), ] cases = [(listToTreeNode(x), d) for x, d in cases] rslts = [solver.countPairs(root, distance) for root, distance in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs[0] else None} + {cs[1:]} | solution: {rs}" )
[node.depth[1][0] + 1, node.depth[1][1]], node.left) if found: return found, leafval if node.right: found, leafval = self.recursive( [node.depth[0][0] + 1, node.depth[0][1]], node.right) if found: return found, leafval return False, None def findClosestLeaf(self, root: TreeNode, k: int) -> int: self.k = k self.preprocess(root) return self.recursive([float('inf'), None], root)[1] if __name__ == '__main__': solver = Solution() cases = [ ([1], 1), ([1, None, 2, 3], 2), ([1, 2, 3, 4, None, None, None, 5, None, 6], 2), ([1, 2, 3, None, None, 4, 5, 6, None, None, 7, 8, 9, 10], 7), ] cases = [(listToTreeNode(x), k) for x, k in cases] rslts = [solver.findClosestLeaf(root, k) for root, k in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs else None}, {cs[1:]} | solution: {rs}" )
x, stack = [], [(root, sum, []), ] if root is not None: while stack: node, val, rslt = stack.pop() if node.left is None and node.right is None and node.val == val: x.append(rslt + [node.val]) if node.right is not None: stack.append((node.right, val - node.val, rslt + [node.val])) if node.left is not None: stack.append((node.left, val - node.val, rslt + [node.val])) return x if __name__ == '__main__': solver = Solution() cases = [ # ([], 0), # false # ([], 1), # false # ([], -1), # false ([1, 2], 1), ([5,4,8,11,None,13,4,7,2,None,None,None,1], 22), ([5,4,8,11,None,13,4,7,2,None,None,5,1], 22), ] cases = [ (listToTreeNode(x), val) for x, val in cases ] rslts = [ solver.pathSum(x, val) for x, val in cases ] for cs, rs in zip(cases, rslts): print(f"case:\n{cs[0].display()}\n{cs[1]}, solution: {rs}")
if node.right: dmaxR, dnumR = self.recursive(node.right, depth + 1) dmax = max(dmaxL, dmaxR) if dmaxL == dmaxR: dnum = dnumL + dnumR else: dnum = dnumL if dmaxL > dmaxR else dnumR # is node LCA of deepest leaves? if dmax > self.dmax or (dmax == self.dmax and dnum > self.dnum): self.ans, self.dmax, self.dnum = node, dmax, dnum return dmax, dnum def lcaDeepestLeaves(self, root: TreeNode) -> TreeNode: self.ans, self.dmax, self.dnum = root, 0, 1 self.recursive(root, 0) return self.ans if __name__ == '__main__': solver = Solution() cases = [ [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, None, 2, 3], ] cases = [listToTreeNode(x) for x in cases] rslts = [solver.lcaDeepestLeaves(root) for root in cases] for cs, rs in zip(cases, rslts): print(f"case:\n{cs.display() if cs else None} | solution:\n{rs}")
if node.left: self.ans.add(node.left) if node.right: self.ans.add(node.right) if node.left: self.recursive(node.left) if node.left.val in self.ds: node.left = None if node.right: self.recursive(node.right) if node.right.val in self.ds: node.right = None def delNodes(self, root: TreeNode, to_delete: List[int]) -> List[TreeNode]: self.ans, self.ds = {root}, set(to_delete) self.recursive(root) return self.ans if __name__ == '__main__': solver = Solution() cases = [ ([1, 2, 3, 4, 5, 6, 7], [3, 5]), ] cases = [(listToTreeNode(x), to_delete) for x, to_delete in cases] rslts = [solver.delNodes(root, to_delete) for root, to_delete in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs[0] else None} + {cs[1]}\nsolution: {rs}" )
ans.append(stack1[-1].val) self._nextLT(stack1) else: ans.append(stack2[-1].val) self._nextGT(stack2) i += 1 return ans if __name__ == '__main__': solver = Solution() cases = [ ([0], 2147483648.0, 1), ([8, 1], 6.0, 1), ([4, 2, 7, 1, 3, 5, 8], 3.72, 2), ([4, 2, 7, 1, 3, 5, 8], 3.14, 3), ([4, 2, 7, 1, 3, 5, 8], 5.14, 4), ([4, 2, 7, 1, 3, 5, 8], 5.98, 2), ([4, 2, 7, 1, 3, 5, 8], 6.18, 4), ([4, 2, 7, 1, 3, 5, 8], 7.12, 3), ([ 8, 5, 17, 3, 7, 14, 19, 1, 4, 6, None, 10, 16, None, None, None, None, None, None, None, None, 9, 12, 15, None, None, None, 11, 13 ], 6.18, 8), ] cases = [(listToTreeNode(x), target, k) for x, target, k in cases] rslts = [ solver.closestKValues(root, target, k) for root, target, k in cases ] for cs, rs in zip(cases, rslts): print(f"case:\n{cs[0].display()}, {cs[1:]} | solution: {rs}")
ans, stack = [], [root] while stack: node = stack.pop() if node.right or node.left: if node.right: stack.append(node.right) if node.left: stack.append(node.left) else: ans.append(node.val) return ans def leafSimilar(self, root1: TreeNode, root2: TreeNode) -> bool: s1, s2 = self.getLeafSequence(root1), self.getLeafSequence(root2) return s1 == s2 if __name__ == '__main__': solver = Solution() cases = [ ([1, 2, 3], [1, None, 2, 3]), ([3, 5, 1, 6, 2, 9, 8, None, None, 7, 4], [3, 5, 1, 6, 7, 4, 2, None, None, None, None, None, None, 9, 8]), ] cases = [(listToTreeNode(x1), listToTreeNode(x2)) for x1, x2 in cases] rslts = [solver.leafSimilar(root1, root2) for root1, root2 in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs[0] else None}\n{cs[1].display() if cs[1] else None}\nsolution: {rs}" )
zs.append(y.next) if x.left: q.append((x.left, zs + [head])) if x.right: q.append((x.right, zs + [head])) return False if __name__ == '__main__': solver = Solution() cases = [ ([4, 2, 8], [ 1, 4, 4, None, 2, 2, None, 1, None, 6, 8, None, None, None, None, 1, 3 ]), ([1, 4, 2, 6], [ 1, 4, 4, None, 2, 2, None, 1, None, 6, 8, None, None, None, None, 1, 3 ]), ([1, 4, 2, 6, 8], [ 1, 4, 4, None, 2, 2, None, 1, None, 6, 8, None, None, None, None, 1, 3 ]), ] cases = [(listToListNode(x), listToTreeNode(y)) for x, y in cases] rslts = [solver.isSubPath(head, root) for head, root in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs[0] else None}\n{cs[1].display() if cs[1] else None}\nsolution: {rs}" )
path[i] += node.val if path[i] == self.sum: self.ans += 1 if node.left: self.recursive(path.copy(), node.left) if node.right: self.recursive(path.copy(), node.right) return None def pathSum(self, root: TreeNode, sum: int) -> int: self.ans, self.sum = 0, sum if root: self.recursive([], root) return self.ans if __name__ == '__main__': solver = Solution() cases = [ ([], 0), ([], 1), ([0], 0), ([1], 1), ([5,4,8,11,None,13,4,7,2,None,None,5,1], 22), ] cases = [ (listToTreeNode(x), s) for x, s in cases ] rslts = [ solver.pathSum(root, sum) for root, sum in cases ] for cs, rs in zip(cases, rslts): print(f"case:\n{cs[0].display() if cs[0] else None} - {cs[1]}, solution: {rs}")
return node while node and (node.val < self.L or node.val > self.R): if node.val < self.L: node = node.right else: # node.val > self.R: node = node.left if node: node.left = self.recursive(node.left) node.right = self.recursive(node.right) return node def trimBST(self, root: TreeNode, L: int, R: int) -> TreeNode: self.L, self.R = L, R return self.recursive(root) if __name__ == '__main__': solver = Solution() cases = [ ([1, None, 2, 3], 1, 2), ([3, 0, 4, None, 1, None, None, 2], 1, 3), ([3, 0, 4, None, 1, None, None, 2], 2, 4), ] cases = [(listToTreeNode(x), L, R) for x, L, R in cases] rslts = [solver.trimBST(root, L, R) for root, L, R in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs else None} + {cs[1:]}\nsolution:\n{rs.display() if rs else None}" )
level, queue = level + 1, [] if level == d - 1: for node in stack: xl, xr = TreeNode(v), TreeNode(v) xl.left, xr.right = node.left, node.right node.left, node.right = xl, xr break else: for node in stack: if node.left: queue.append(node.left) if node.right: queue.append(node.right) stack = queue return root if __name__ == '__main__': solver = Solution() cases = [ ([1,None,2,3], 1, 1), ([1,None,2,3], 1, 2), ] cases = [ (listToTreeNode(x), v, d) for x, v, d in cases ] rslts = [ solver.addOneRow(root, v, d) for root, v, d in cases ] for cs, rs in zip(cases, rslts): print(f"case:\n{cs[0].display() if cs[0] else None}, {cs[1:]} | solution:\n{rs.display() if rs else None}")
node = stack.pop() x.append(node.val) node = node.right return x def getAllElements(self, root1: TreeNode, root2: TreeNode) -> List[int]: # merge 2 sorted list in O(N) arr1, arr2 = self.inorderTraversal(root1), self.inorderTraversal(root2) ans, i1, i2, n1, n2 = [], 0, 0, len(arr1), len(arr2) while i1 < n1 or i2 < n2: if (i1 < n1 and i2 < n2 and arr1[i1] <= arr2[i2]) or i2 == n2: ans.append(arr1[i1]) i1 += 1 else: ans.append(arr2[i2]) i2 += 1 return ans if __name__ == '__main__': solver = Solution() cases = [ ([2,1,4], [1,0,3]), ] cases = [ (listToTreeNode(x), listToTreeNode(y)) for x, y in cases ] rslts = [ solver.getAllElements(root1, root2) for root1, root2 in cases ] for cs, rs in zip(cases, rslts): print(f"case:\n{cs[0].display() if cs else None}\n{cs[1].display() if cs else None}\nsolution: {rs}")
class Solution: def splitBST(self, root: TreeNode, V: int) -> List[TreeNode]: if not root: return None, None elif root.val > V: node, root.left = self.splitBST(root.left, V) return node, root else: root.right, node = self.splitBST(root.right, V) return root, node if __name__ == '__main__': solver = Solution() cases = [ ([4, 2, 6, 1, 3, 5, 7], 1), ([4, 2, 6, 1, 3, 5, 7], 2), ([4, 2, 6, 1, 3, 5, 7], 3), ([4, 2, 6, 1, 3, 5, 7], 4), ([4, 2, 6, 1, 3, 5, 7], 5), ([4, 2, 6, 1, 3, 5, 7], 6), ([4, 2, 6, 1, 3, 5, 7], 7), ] cases = [(listToTreeNode(x), V) for x, V in cases] rslts = [solver.splitBST(root, V) for root, V in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs else None} + {cs[1:]} |\nsolution:\n{rs[0].display() if rs[0] else None}\n{rs[1].display() if rs[1] else None}" )
else: if root.left: root.val = self.predcessor(root) root.left = self.deleteNode(root.left, root.val) elif root.right: root.val = self.successor(root) root.right = self.deleteNode(root.right, root.val) else: root = None return root if __name__ == '__main__': solver = Solution() cases = [ ([], 0), ([1], 1), ([3, 2, None, 1], 2), ([1, None, 2, None, 3], 2), ([ 20, 16, 22, 12, 18, 21, 23, 2, 14, 17, 19, None, None, None, None, 1, 6, 13, 15, None, None, None, None, None, None, 4, 8, None, None, None, None, 3, 5, 7, 9, None, None, None, None, None, None, 8, 11 ], 12), ] cases = [(listToTreeNode(x), key) for x, key in cases] rslts = [solver.deleteNode(root, key) for root, key in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs[0] else None} + {cs[1]}\nsolution:\n{rs.display() if rs else None}" )
class Solution: def isValidSequence(self, root: TreeNode, arr: List[int]) -> bool: queue = [root] for x in arr: if not queue: return False queue = list( itertools.chain.from_iterable((node.left, node.right) for node in queue if node and node.val == x)) for l, r in zip(queue[::2], queue[1::2]): if not (l or r): return True return False if __name__ == '__main__': solver = Solution() cases = [ ([8, 3, None, 2, 1, 5, 4], [8]), ([0, 1, 0, 0, 1, 0, None, None, 1, 0, 0], [0, 0, 1]), ([0, 1, 0, 0, 1, 0, None, None, 1, 0, 0], [0, 1, 1]), ([0, 1, 0, 0, 1, 0, None, None, 1, 0, 0], [0, 1, 0, 1]), ] cases = [(listToTreeNode(x), arr) for x, arr in cases] rslts = [solver.isValidSequence(root, arr) for root, arr in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs[0] else None} + {cs[1:]} | solution: {rs}" )
if R == [-1]: return [-1] return X + L + R except ValueError as identifier: return [-1] elif root.left: return self.flipMatchVoyage(root.left, voyage[1:]) elif root.right: return self.flipMatchVoyage(root.right, voyage[1:]) else: return [] else: return [-1] if __name__ == '__main__': solver = Solution() cases = [ ([1,2,3], [1,2,3]), ([1,2,3], [1,3,2]), ([1,2,3], [2,1,3]), ] cases = [ (listToTreeNode(x), voyage) for x, voyage in cases ] rslts = [ solver.flipMatchVoyage(root, voyage) for root, voyage in cases ] for cs, rs in zip(cases, rslts): print(f"case:\n{cs[0].display() if cs[0] else None}\n+{cs[1:]} | solution: {rs}")
"""Exact copy of 0102, except return list(reversed(x)). """ if root is None: return [] stack, x = [ (0, root), ], [] while stack: level, node = stack.pop() while level >= len(x): x.append([]) x[level].append(node.val) if node.right is not None: stack.append((level + 1, node.right)) if node.left is not None: stack.append((level + 1, node.left)) return list(reversed(x)) if __name__ == '__main__': solver = Solution() cases = [ # [], [1, None, 2, 3], [3, 9, 20, None, None, 15, 7], ] cases = [(listToTreeNode(x)) for x in cases] rslts = [solver.levelOrderBottom(x) for x in cases] for cs, rs in zip(cases, rslts): print(f"case:\n{cs.display()}, solution: {rs}")
if node.right: # sufficient on any left sR = self.recursive(node.right, x) if not sR: node.right = None return sL or sR else: # leaf node return x >= self.limit def sufficientSubset(self, root: TreeNode, limit: int) -> TreeNode: self.limit = limit # node is insufficient iff all sub-nodes are insufficient ss = self.recursive(root, 0) return root if ss else None if __name__ == '__main__': solver = Solution() cases = [ ([1, None, 2, 3], 4), ([1, None, 2, 3], 7), ([5, 4, 8, 11, None, 17, 4, 7, 1, None, None, 5, 3], 22), ] cases = [(listToTreeNode(x), limit) for x, limit in cases] rslts = [solver.sufficientSubset(root, limit) for root, limit in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs[0] else None} + {cs[1]}\nsolution:\n{rs.display() if rs else None}" )
return None if node.val == self.y: self.dp[1] = (depth, parent) if self.dp[0][0]: return None if node.left: self.recursive(node.left, depth + 1, node.val) if node.right: self.recursive(node.right, depth + 1, node.val) def isCousins(self, root: TreeNode, x: int, y: int) -> bool: # dp: (depth, parent) self.dp = [(None, None), (None, None)] self.x, self.y = x, y self.recursive(root, 0, '') return self.dp[0][0] == self.dp[1][0] and self.dp[0][1] != self.dp[1][1] if __name__ == '__main__': solver = Solution() cases = [ ([1, None, 2, 3], 2, 3), ([1, 2, 3, None, 4, None, 5], 5, 4), ] cases = [(listToTreeNode(r), x, y) for r, x, y in cases] rslts = [solver.isCousins(root, x, y) for root, x, y in cases] for cs, rs in zip(cases, rslts): print( f"case:\n{cs[0].display() if cs[0] else None}\n+{cs[1:]} | solution: {rs}" )
class Solution: def recursive(self, node): if node.left: node.left = self.recursive(node.left) if node.right: node.right = self.recursive(node.right) if (node.left is None) and (node.right is None) and node.val == self.target: return None return node def removeLeafNodes(self, root: TreeNode, target: int) -> TreeNode: self.target = target return self.recursive(root) if __name__ == '__main__': solver = Solution() cases = [ ([1,1,1], 1), ([1,2,3,4], 2), ([1,3,3,3,2], 3), ([1,2,3,2,None,2,4], 2), ([1,2,None,2,None,2], 2), ] cases = [ (listToTreeNode(x), target) for x, target in cases ] rslts = [ solver.removeLeafNodes(root, target) for root, target in cases ] for cs, rs in zip(cases, rslts): print(f"case:\n{cs[0].display() if cs[0] else None} + {cs[1:]}\nsolution:\n{rs.display() if rs else None}")