Ejemplo n.º 1
0
        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}"
        )
Ejemplo n.º 2
0
        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}"
        )
Ejemplo n.º 3
0
                    [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}"
        )
Ejemplo n.º 4
0
    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}")
Ejemplo n.º 5
0
            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}")
Ejemplo n.º 6
0
            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}"
        )
Ejemplo n.º 7
0
                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}")
Ejemplo n.º 8
0
        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}"
        )
Ejemplo n.º 9
0
                    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}"
        )
Ejemplo n.º 10
0
      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}")
Ejemplo n.º 11
0
            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}"
        )
Ejemplo n.º 12
0
        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}")
Ejemplo n.º 13
0
        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}")
Ejemplo n.º 14
0
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}"
        )
Ejemplo n.º 15
0
        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}"
        )
Ejemplo n.º 17
0
            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}")
Ejemplo n.º 18
0
        """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}")
Ejemplo n.º 19
0
            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}"
        )
Ejemplo n.º 20
0
                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}"
        )
Ejemplo n.º 21
0
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}")