示例#1
0
class Solution:
    def getTargetCopy(self, original: TreeNode, cloned: TreeNode,
                      target: TreeNode) -> TreeNode:
        if not original:
            return None
        if target is original:
            return cloned
        return self.getTargetCopy(original.left, cloned.left,
                                  target) or self.getTargetCopy(
                                      original.right, cloned.right, target)


if __name__ == "__main__":
    # 3
    tree1 = build_TreeNode([7, 4, 3, None, None, 6, 19])
    tree2 = copy.deepcopy(tree1)
    print(Solution().getTargetCopy(tree1, tree2, tree1.right))

    # 7
    tree1 = build_TreeNode([1])
    tree2 = copy.deepcopy(tree1)
    print(Solution().getTargetCopy(tree1, tree2, tree1))

    # 4
    tree1 = build_TreeNode(
        [8, None, 6, None, 5, None, 4, None, 3, None, 2, None, 1])
    tree2 = copy.deepcopy(tree1)
    print(Solution().getTargetCopy(tree1, tree2, tree1.right.right.right))

    # 5
示例#2
0
                if node.right:
                    queue.append(node.right)
            d -= 1

        print(queue)

        # 增加新的一行
        for node in queue:
            if node.left:
                new_node = TreeNode(v)
                new_node.left = node.left
                node.left = new_node
            else:
                node.left = TreeNode(v)
            if node.right:
                new_node = TreeNode(v)
                new_node.right = node.right
                node.right = new_node
            else:
                node.right = TreeNode(v)

        return root


if __name__ == "__main__":
    # [4,1,1,2,None,None,6,3,1,5]
    print(Solution().addOneRow(build_TreeNode([4, 2, 6, 3, 1, 5]), 1, 2))

    # [1,2,3,4,null,null,null,5,5]
    print(Solution().addOneRow(build_TreeNode([1, 2, 3, 4]), 5, 4))
示例#3
0
from toolkit import TreeNode, build_TreeNode


class Solution:
    def trimBST(self, root: TreeNode, L: int, R: int) -> TreeNode:
        def helper(node):
            if not node:
                return None
            if L <= node.val <= R:
                node.left = helper(node.left)
                node.right = helper(node.right)
                return node
            elif node.val < L:
                return helper(node.right)
            elif node.val > R:
                return helper(node.left)

        return helper(root)


if __name__ == "__main__":
    print(Solution().trimBST(build_TreeNode([1, 0, 2]), 1, 2))  # [1,None,2]
    print(Solution().trimBST(build_TreeNode([3, 0, 4, None, 2, None, None, 1]),
                             1, 3))  # [3,2,None,1]
示例#4
0
            # 处理根节点的值不相等的情况
            if node.val != self.voyage[self.i]:
                self.ans = [-1]
                return

            self.i += 1

            if node.left and self.i < len(
                    self.voyage) and node.left.val != self.voyage[self.i]:
                self.ans.append(node.val)
                self.dfs(node.right)
                self.dfs(node.left)
            else:
                self.dfs(node.left)
                self.dfs(node.right)

    def flipMatchVoyage(self, root: TreeNode, voyage: List[int]) -> List[int]:
        self.voyage = voyage
        self.dfs(root)
        if self.ans and self.ans[0] == -1:
            return [-1]
        return self.ans


if __name__ == "__main__":
    print(Solution().flipMatchVoyage(build_TreeNode([1, 2]), [2, 1]))  # [-1]
    print(Solution().flipMatchVoyage(build_TreeNode([1, 2, 3]),
                                     [1, 3, 2]))  # [1]
    print(Solution().flipMatchVoyage(build_TreeNode([1, 2, 3]),
                                     [1, 2, 3]))  # []
示例#5
0
                node.left = None
            if node.right and dfs(node.right):
                node.right = None
            return not node.left and not node.right and node.val == target

        dfs(root)

        if not root.left and not root.right and root.val == target:
            return None

        return root


if __name__ == "__main__":
    # [1,null,3,null,4]
    print(Solution().removeLeafNodes(build_TreeNode([1, 2, 3, 2, None, 2, 4]),
                                     2))

    # [1,3,null,null,2]
    print(Solution().removeLeafNodes(build_TreeNode([1, 3, 3, 3, 2]), 3))

    # [1]
    print(Solution().removeLeafNodes(build_TreeNode([1, 2, None, 2, None, 2]),
                                     2))

    # []]
    print(Solution().removeLeafNodes(build_TreeNode([1, 1, 1]), 1))

    # [1,2,3]
    print(Solution().removeLeafNodes(build_TreeNode([1, 2, 3]), 1))
示例#6
0

class Solution:
    def rob(self, root: TreeNode) -> int:
        def recursor(node):
            # 处理当前节点不存在的情况
            if not node:
                return 0, 0

            # 左子树最大值(盗窃左节点和不盗窃左节点的两种情况)
            left1, left2 = recursor(node.left)

            # 右子树最大值(盗窃右节点和不盗窃右节点的两种情况)
            right1, right2 = recursor(node.right)

            # 盗窃当前节点并继续向根节点盗窃所能提供的最大值
            most_maybe1 = node.val + left2 + right2

            # 不盗窃当前节点并继续向根节点盗窃所能提供的最大值
            most_maybe2 = max(left1, left2) + max(right1, right2)  # 使用左子树和右子树的最大值,不盗窃当前节点

            return most_maybe1, most_maybe2

        return max(recursor(root))


if __name__ == "__main__":
    print(Solution().rob(build_TreeNode([3, 2, 3, None, 3, None, 1])))  # 7
    print(Solution().rob(build_TreeNode([3, 4, 5, 1, 3, None, 1])))  # 9
    print(Solution().rob(build_TreeNode([4, 2, None, 1, 3])))  # 9
示例#7
0

class Solution:
    def lcaDeepestLeaves(self, root: TreeNode) -> TreeNode:
        def dfs(node, depth):
            if not node:
                return None, 0
            if not node.left and not node.right:
                return node, depth
            left, depth_left = dfs(node.left, depth + 1)
            right, depth_right = dfs(node.right, depth + 1)
            if depth_left == depth_right:
                return node, depth_left
            elif depth_left > depth_right:
                return left, depth_left
            else:
                return right, depth_right

        return dfs(root, 1)[0]


if __name__ == "__main__":
    # [1,2,3]
    print(Solution().lcaDeepestLeaves(build_TreeNode([1, 2, 3])))

    # [4]
    print(Solution().lcaDeepestLeaves(build_TreeNode([1, 2, 3, 4])))

    # [2,4,5]
    print(Solution().lcaDeepestLeaves(build_TreeNode([1, 2, 3, 4, 5])))
示例#8
0
            if node:
                stack.append(node.left)
            else:
                stack.pop()
                if not stack:
                    break
                now = stack.pop()
                self.ans.append(now.val)
                stack.append(now.right)
            print(stack)

    def next(self) -> int:
        return self.ans.pop(0)

    def hasNext(self) -> bool:
        return len(self.ans) > 0


if __name__ == "__main__":
    root = build_TreeNode([7, 3, 15, None, None, 9, 20])
    obj = BSTIterator(root)
    print(obj.next())  # 3
    print(obj.next())  # 7
    print(obj.hasNext())  # True
    print(obj.next())  # 9
    print(obj.hasNext())  # True
    print(obj.next())  # 15
    print(obj.hasNext())  # True
    print(obj.next())  # 20
    print(obj.hasNext())  # False
示例#9
0
class Solution:
    def __init__(self):
        self.depth = None
        self.father = None

    def isCousins(self, root: TreeNode, x: int, y: int) -> bool:
        def helper(node, depth=0, father=None):
            if node:
                if node.val == x or node.val == y:
                    if self.depth is None:
                        self.depth = depth + 1
                        self.father = father
                    else:
                        if self.depth == depth + 1 and self.father != father:
                            return True
                        else:
                            return False
                return helper(node.left, depth + 1, node.val) or helper(
                    node.right, depth + 1, node.val)

        return helper(root)


if __name__ == "__main__":
    print(Solution().isCousins(build_TreeNode([1, 2, 3, 4]), 4, 3))  # False
    print(Solution().isCousins(build_TreeNode([1, 2, 3, None, 4, None, 5]), 5,
                               4))  # True
    print(Solution().isCousins(build_TreeNode([1, 2, 3, None, 4]), 2,
                               3))  # False
示例#10
0
from toolkit import TreeNode
from toolkit import build_TreeNode


class Solution:

    def findBottomLeftValue(self, root: TreeNode) -> int:
        ans = root.val
        queue = collections.deque([root])

        while queue:
            for _ in range(len(queue)):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            if queue:
                ans = queue[0].val

        return ans


if __name__ == "__main__":
    # 1
    print(Solution().findBottomLeftValue(build_TreeNode([2, 1, 3])))

    # 7
    print(Solution().findBottomLeftValue(build_TreeNode([1, 2, 3, 4, None, 5, 6, None, None, 7])))
示例#11
0
from toolkit import TreeNode, build_TreeNode


class Solution:
    def findTarget(self, root: TreeNode, k: int) -> bool:
        def helper(node):
            if not node:
                return []
            return helper(node.left) + [node.val] + helper(node.right)

        nums = helper(root)

        hashmap = []

        for n in nums:
            if k - n not in hashmap:
                hashmap.append(n)
            else:
                return True
        else:
            return False


if __name__ == "__main__":
    print(Solution().findTarget(build_TreeNode([5, 3, 6, 2, 4, None, 7]),
                                9))  # True
    print(Solution().findTarget(build_TreeNode([5, 3, 6, 2, 4, None, 7]),
                                28))  # False
示例#12
0
from toolkit import TreeNode
from toolkit import build_TreeNode


class Solution:
    def pruneTree(self, root: TreeNode) -> TreeNode:
        if root:
            root.left = self.pruneTree(root.left)
            root.right = self.pruneTree(root.right)
            if root.val == 1 or root.left or root.right:
                return root


if __name__ == "__main__":
    # [1,None,0,None,1]
    print(Solution().pruneTree(build_TreeNode([1, None, 0, 0, 1])))

    # [1,None,1,None,1]
    print(Solution().pruneTree(build_TreeNode([1, 0, 1, 0, 0, 0, 1])))

    # [1,1,0,1,1,None,1]
    print(Solution().pruneTree(build_TreeNode([1, 1, 0, 1, 1, 0, 1, 0])))
示例#13
0
from toolkit import TreeNode, build_TreeNode


class Solution:
    def __init__(self):
        self.val = None

    def isUnivalTree(self, root: TreeNode) -> bool:
        self.val = root.val

        def helper(node):
            if not node:
                return True
            elif node.val != self.val:
                return False
            else:
                return helper(node.left) and helper(node.right)

        return helper(root)


if __name__ == "__main__":
    tree = build_TreeNode([1, 1, 1, 1, 1, None, 1])
    print(Solution().isUnivalTree(tree))  # True
    tree = build_TreeNode([2, 2, 2, 5, 2])
    print(Solution().isUnivalTree(tree))  # False
示例#14
0
class Solution:
    def rightSideView(self, root: TreeNode) -> List[int]:
        # 处理特殊情况
        if not root:
            return []

        # 处理一般情况
        ans = [root.val]
        stack = [(root, 0)]
        while stack:
            node, level = stack[-1]
            if node.right:
                stack.append((node.right, level + 1))
                if level + 1 == len(ans):
                    ans.append(node.right.val)
            else:
                while stack:
                    node, level = stack.pop()
                    if node.left:
                        stack.append((node.left, level + 1))
                        if level + 1 == len(ans):
                            ans.append(node.left.val)
                        break
        return ans


if __name__ == "__main__":
    print(Solution().rightSideView(build_TreeNode([1, 2, 3, None, 5, None,
                                                   4])))  # [1,3,4]
    print(Solution().rightSideView(build_TreeNode([1, 2])))  # [1,2]
示例#15
0
                return 0

            left_length = 0
            right_length = 0
            if node.left:
                if node.val == node.left.val:
                    left_length = helper(node.left) + 1
                else:
                    helper(node.left)
            if node.right:
                if node.val == node.right.val:
                    right_length = helper(node.right) + 1
                else:
                    helper(node.right)
            if left_length > 0 and right_length > 0:
                self.max = max(self.max, left_length + right_length)
            else:
                self.max = max(self.max, left_length, right_length)
            return max(left_length, right_length)

        helper(root)

        return self.max


if __name__ == "__main__":
    print(Solution().longestUnivaluePath(
        build_TreeNode([5, 4, 5, 1, 1, None, 5])))  # 2
    print(Solution().longestUnivaluePath(
        build_TreeNode([1, 4, 5, 4, 4, None, 5])))  # 2
示例#16
0
                left = 0

            if node.right:
                right = dfs(node.right)[0]
            else:
                right = 0

            self.max = max(self.max, left, right)

            return left + 1, right + 1

        dfs(root)

        return self.max


if __name__ == "__main__":
    # 3
    print(Solution().longestZigZag(
        build_TreeNode([
            1, None, 1, 1, 1, None, None, 1, 1, None, 1, None, None, None, 1,
            None, 1
        ])))

    # 4
    print(Solution().longestZigZag(
        build_TreeNode([1, 1, 1, None, 1, None, None, 1, 1, None, 1])))

    # 0
    print(Solution().longestZigZag(build_TreeNode([1])))
示例#17
0
        self.this = False  # 上一个为目标节点

    def inorderSuccessor(self, root: TreeNode, p: TreeNode) -> TreeNode:
        self.aim = p
        self.dfs(root)
        return self.ans

    def dfs(self, node):
        if node:
            self.dfs(node.left)

            if self.this:
                self.ans = node
                self.this = False
            else:
                if node == self.aim:
                    self.this = True

                if node.right:
                    self.dfs(node.right)


if __name__ == "__main__":
    # 2
    tree = build_TreeNode([2, 1, 3])
    print(Solution().inorderSuccessor(tree, tree.left))

    # None
    tree = build_TreeNode([5, 3, 6, 2, 4, None, None, 1])
    print(Solution().inorderSuccessor(tree, tree.right))
示例#18
0
from toolkit import TreeNode, build_TreeNode


class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        pass


if __name__ == "__main__":
    tree = build_TreeNode([6, 2, 8, 0, 4, 7, 9, None, None, 3, 5])
    print(Solution().lowestCommonAncestor(tree, tree.left, tree.right))  # 6
    print(Solution().lowestCommonAncestor(tree, tree.left, tree.left.right))  # 2
示例#19
0
from toolkit import TreeNode, build_TreeNode


class Solution:
    def tree2str(self, t: TreeNode) -> str:
        def helper(node):
            if not node:
                return ""
            if node.left and node.right:
                return str(node.val) + "(" + helper(node.left) + ")(" + helper(
                    node.right) + ")"
            elif node.left:
                return str(node.val) + "(" + helper(node.left) + ")"
            elif node.right:
                return str(node.val) + "()(" + helper(node.right) + ")"
            else:
                return str(node.val)

        return helper(t)


if __name__ == "__main__":
    print(Solution().tree2str(build_TreeNode([1, 2, 3, 4])))  # 1(2(4))(3)
    print(Solution().tree2str(build_TreeNode([1, 2, 3, None,
                                              4])))  # 1(2()(4))(3)
示例#20
0
    def __init__(self):
        self.ans = []

    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
        def recursor(node, stack, _sum):
            if node:
                stack.append(node.val)  # 记录当前路径
                _sum += node.val  # 计算当前路径和

                if not node.left and not node.right:
                    if _sum == sum:
                        self.ans.append(stack)
                else:
                    if node.left:
                        recursor(node.left, stack.copy(), _sum)
                    if node.right:
                        recursor(node.right, stack.copy(), _sum)

        recursor(root, [], 0)
        return self.ans


if __name__ == "__main__":
    # [
    #    [5,4,11,2],
    #    [5,8,4,5]
    # ]
    print(Solution().pathSum(
        build_TreeNode([5, 4, 8, 11, None, 13, 4, 7, 2, None, None, 5, 1]),
        22))
示例#21
0
            if node.left and node.right:
                left = dfs(node.left)
                right = dfs(node.right)
                for i in range(distance - 1):
                    for j in range(0, distance - 1 - i):
                        self.ans += left[i] * right[j]
                return [0] + [left[i] + right[i] for i in range(distance - 1)]
            elif node.left:
                left = dfs(node.left)
                return [0] + left[:-1]
            elif node.right:
                right = dfs(node.right)
                return [0] + right[:-1]
            else:
                return [1] + [0] * (distance - 2)

        dfs(root)

        return self.ans


if __name__ == "__main__":
    print(Solution().countPairs(build_TreeNode([1, 2, 3, None, 4]), 3))  # 1
    print(Solution().countPairs(build_TreeNode([1, 2, 3, 4, 5, 6, 7]), 3))  # 2
    print(Solution().countPairs(
        build_TreeNode(
            [7, 1, 4, 6, None, 5, 3, None, None, None, None, None, 2]),
        3))  # 1
    print(Solution().countPairs(build_TreeNode([1100]), 1))  # 0
    print(Solution().countPairs(build_TreeNode([1, 1, 1]), 2))  # 1
示例#22
0
from toolkit import TreeNode
from toolkit import build_TreeNode


class Solution:
    def subtreeWithAllDeepest(self, root: TreeNode) -> TreeNode:
        # 计算二叉树的最大深度
        def max_depth(node):
            if not node:
                return 0
            return max(max_depth(node.left), max_depth(node.right)) + 1

        def recursor(node):
            depth_left = max_depth(node.left)
            depth_right = max_depth(node.right)
            if depth_left == depth_right:
                return node
            else:
                return recursor(
                    node.left) if depth_left > depth_right else recursor(
                        node.right)

        return recursor(root)


if __name__ == "__main__":
    # [2,7,4]
    print(Solution().subtreeWithAllDeepest(
        build_TreeNode([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4])))
示例#23
0

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        # 处理特殊情况
        if not root:
            return []

        stack = [root]
        ans = []
        while stack:
            if now := stack[-1]:
                stack.append(now.left)
            else:
                stack.pop()
                if not stack:
                    break
                now = stack.pop()
                ans.append(now.val)
                stack.append(now.right)

        return ans


if __name__ == "__main__":
    print(Solution().inorderTraversal(build_TreeNode([1, None, 2,
                                                      3])))  # [1,3,2]
    print(Solution().inorderTraversal(build_TreeNode([1, 2])))  # [2,1]
    print(Solution().inorderTraversal(build_TreeNode([3, 1, None, None,
                                                      2])))  # [1,2,3]
示例#24
0
class Solution:
    def __init__(self):
        self.ans = collections.defaultdict(list)

    def verticalTraversal(self, root: TreeNode) -> List[List[int]]:
        def dfs(node, idx, level):
            if node:
                self.ans[idx].append((node.val, level))
                if node.left:
                    dfs(node.left, idx - 1, level + 1)
                if node.right:
                    dfs(node.right, idx + 1, level + 1)

        dfs(root, 0, 0)
        ans = []
        for k in sorted(self.ans.keys()):
            ans.append([
                elem[0]
                for elem in sorted(self.ans[k], key=lambda x: (x[1], x[0]))
            ])
        return ans


if __name__ == "__main__":
    # [[9],[3,15],[20],[7]]
    print(Solution().verticalTraversal(
        build_TreeNode([3, 9, 20, None, None, 15, 7])))

    # [[4],[2],[1,5,6],[3],[7]]
    print(Solution().verticalTraversal(build_TreeNode([1, 2, 3, 4, 5, 6, 7])))
示例#25
0
        self.min1 = float("inf")
        self.min2 = float("inf")

    def findSecondMinimumValue(self, root: TreeNode) -> int:
        def helper(node):
            if node.val < self.min1:
                self.min2 = self.min1
                self.min1 = node.val
            elif self.min1 < node.val < self.min2:
                self.min2 = node.val
            if node.left and node.right:
                if node.left.val < self.min2:
                    helper(node.left)
                if node.right.val < self.min2:
                    helper(node.right)

        helper(root)

        if self.min2 == float("inf"):
            return -1
        else:
            return int(self.min2)


if __name__ == "__main__":
    print(Solution().findSecondMinimumValue(
        build_TreeNode([2, 2, 5, None, None, 5, 7])))  # 5
    print(Solution().findSecondMinimumValue(build_TreeNode([2, 2, 2])))  # -1
    print(Solution().findSecondMinimumValue(
        build_TreeNode([2, 2, 5, None, None, 5, 5])))  # 5
示例#26
0
from toolkit import TreeNode,build_TreeNode


class Solution:
    def hasPathSum(self, root: TreeNode, sum: int) -> bool:
        if root is None:
            return False

        node_dict = {root: root.val}
        while len(node_dict) > 0:
            temp_node_dict = {}
            for node in node_dict:
                node_value = node_dict[node]
                if node.left is None and node.right is None:
                    if node_value == sum:
                        return True
                if node.left is not None:
                    temp_node_dict[node.left] = node_value + node.left.val
                if node.right is not None:
                    temp_node_dict[node.right] = node_value + node.right.val
            node_dict = temp_node_dict
        return False


if __name__ == "__main__":
    print(Solution().hasPathSum(build_TreeNode([5, 4, 8, 11, None, 13, 4, 7, 2, None, None, None, 1]), 22))
    print(Solution().hasPathSum(build_TreeNode([1]), 1))
import collections
from typing import List

from toolkit import TreeNode
from toolkit import build_TreeNode


class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        if not root:
            return []

        ans = []
        queue = collections.deque([root])
        while queue:
            node = queue.popleft()
            ans.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        return ans


if __name__ == "__main__":
    # [3,9,20,15,7]
    print(Solution().levelOrder(build_TreeNode([3, 9, 20, None, None, 15, 7])))
示例#28
0
        if not root:
            return 0., 0.

        # 递归左子树和右子树
        total_left, full_left = self.dfs(root.left)
        total_right, full_right = self.dfs(root.right)

        # 计算树的总计运行时间
        total_root = root.val + total_left + total_right

        if total_left < total_right:
            total_left, total_right = total_right, total_left
            full_left, full_right = full_right, full_left

        # 处理左子节点和右子节点均可以完全双线程的情况
        if total_left - 2 * full_left <= total_right:
            full_root = (total_left + total_right) / 2

        # 处理左子节点和右子节点不能完全双线程的情况
        else:
            full_root = total_right + full_left

        return total_root, full_root


if __name__ == "__main__":
    print(Solution().minimalExecTime(build_TreeNode([47, 74, 31])))  # 121
    print(Solution().minimalExecTime(build_TreeNode([15, 21, None, 24, None, 27, 26])))  # 87
    print(Solution().minimalExecTime(build_TreeNode([1, 3, 2, None, None, 4, 4])))  # 7.5
    print(Solution().minimalExecTime(build_TreeNode([75, None, 18, None, 20, 27, 36])))  # 149
示例#29
0
from toolkit import TreeNode, build_TreeNode


class Solution:
    def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode:
        def helper(node1, node2):
            if node1 and node2:
                node = TreeNode(node1.val + node2.val)
                node.left = helper(node1.left, node2.left)
                node.right = helper(node1.right, node2.right)
                return node
            elif node1:
                return node1
            elif node2:
                return node2
            else:
                return None

        return helper(t1, t2)


if __name__ == "__main__":
    # [3,4,5,5,4,None,7]
    print(Solution().mergeTrees(build_TreeNode([1, 3, 2, 5]),
                                build_TreeNode([2, 1, 3, None, 4, None, 7])))
示例#30
0
from toolkit import TreeNode, build_TreeNode


class Solution:
    def minDepth(self, root: TreeNode) -> int:
        if root is None:
            return 0
        level = 1
        node_list = [root]
        while len(node_list) > 0:
            temp_node_list = []
            for node in node_list:
                if node.left is None and node.right is None:
                    return level
                if node.left is not None:
                    temp_node_list.append(node.left)
                if node.right is not None:
                    temp_node_list.append(node.right)
            node_list = temp_node_list
            level += 1
        return level


if __name__ == "__main__":
    print(Solution().minDepth(build_TreeNode([3, 9, 20, None, None, 15,
                                              7])))  # 2
    print(Solution().minDepth(build_TreeNode([1, 2])))
    print(Solution().minDepth(build_TreeNode([1, 2, 3, 4, 5])))