from src.common.tree import create_treenode
from src.common.list import ListNode


class Solution:
    def treeToDoublyList(self, root):
        def dfs(node):
            nonlocal pre, head
            if not node: return
            dfs(node.left)
            if pre:
                pre.right, node.left = node, pre
            else:
                head = node
            pre = node
            dfs(node.right)

        if not root: return
        pre = head = None
        dfs(root)
        head.left, pre.right = pre, head
        return head


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([4, 2, 5, 1, 3])
    print(root)
    print('1', s.treeToDoublyList(root))
因此,数字总和 = 495 + 491 + 40 = 1026

提示:

树中节点的数目在范围 [1, 1000] 内
0 <= Node.val <= 9
树的深度不超过 10
'''


class Solution:
    def sumNumbers(self, root) -> int:
        if not root:return 0
        def dfs(node,pre_value):
            if not node: return 0
            total =pre_value*10+node.value
            if not node.left and not node.right:
                return total
            else:
                return dfs(node.left,total) + dfs(node.right,total)
        return dfs(root,0)
if __name__ =='__main__':
    s =Solution()
    from src.common.tree import create_treenode
    root = create_treenode([1, 2, 3])
    print(root)
    print('1',s.sumNumbers(root))
    root = create_treenode([4, 9, 0, 5, 1])
    print(root)
    print('1',s.sumNumbers(root))
                current_level.append(node.value)
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
            ret.append(current_level)
        return ret

    def levelOrder2(self, root):  # dfs
        if not root: return []

        def dfs(node, level):
            if not node: return
            if level > len(ret):
                ret.append([])
            ret[level - 1].append(node.value)
            dfs(node.left, level + 1)
            dfs(node.right, level + 1)

        ret = []
        dfs(root, 1)
        return ret


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([3, 9, 20, None, None, 15, 7])
    print(root)
    print('1', s.levelOrder(root))
    print('2', s.levelOrder2(root))
Example #4
0
        #O(n)
        if p.value < root.value > q.value:
            root = self.lowestCommonAncestor1(root.left, p, q)
        if p.value > root.value < q.value:
            root = self.lowestCommonAncestor1(root.right, p, q)
        return root

    def lowestCommonAncestor2(self, root, p, q):
        #O(n)
        while root:
            if p.value < root.value > q.value:
                root = root.left
            elif p.value > root.value < q.value:
                root = root.right
            else:
                return root


if __name__ == "__main__":
    s = Solution()
    tree_node = create_treenode([6, 2, 8, 0, 4, 7, 9, None, None, 3, 5])
    p = create_treenode([2, 8, 0, 4, 7, 9, None, None, 3, 5])
    q = create_treenode([8, 0, 4, 7, 9, None, None, 3, 5])
    print('1', s.lowestCommonAncestor1(tree_node, p, q).value)
    print('2', s.lowestCommonAncestor2(tree_node, p, q).value)
    tree_node = create_treenode([6, 2, 8, 0, 4, 7, 9, None, None, 3, 5])
    p = create_treenode([2])
    q = create_treenode([4])
    print('1', s.lowestCommonAncestor1(tree_node, p, q).value)
    print('2', s.lowestCommonAncestor2(tree_node, p, q).value)
        if not root: return []
        #时间复杂度O(n) 空间复杂度O(n)
        import collections
        q = collections.deque([root])
        ret = []
        level = 1
        while q:
            current_level = collections.deque()
            for _ in range(len(q)):
                node = q.popleft()
                if level & 1:
                    current_level.append(node.value)
                else:
                    current_level.appendleft(node.value)
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
            level += 1
            ret.append(list(current_level))
        return ret


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([3, 9, 20, None, None, 15, 7])
    print('1', s.zigzagLevelOrder(root))
    root = create_treenode([1, 2, 3, 4, None, None, 5])
    print(root)
    print('1', s.zigzagLevelOrder(root))  # [[1],[3,2],[4,5]]
Example #6
0
-1000 <= targetSum <= 1000
'''


class Solution:
    def hasPathSum(self, root, targetSum: int) -> bool:
        if not root:return False
        targetSum -=root.value
        if not root.left and not root.right and targetSum ==0:
            return True
        return self.hasPathSum(root.left, targetSum) or self.hasPathSum(root.right, targetSum)


if __name__ == '__main__':
    s = Solution()
    from src.common.tree import create_treenode
    root = create_treenode(
        [5, 4, 8, 11, None, 13, 4, 7, 2, None, None, None, None, None, 1])
    targetSum = 22
    print(root)
    print('1', s.hasPathSum(root, targetSum))
    root = create_treenode([1, 2, 3]
                           )
    targetSum = 5
    print(root)
    print('1', s.hasPathSum(root, targetSum))
    root = create_treenode([1, 2])
    targetSum = 0
    print(root)
    print('1', s.hasPathSum(root, targetSum))
Example #7
0
-104 <= Node.val <= 104
'''
from src.common.tree import create_treenode


class Solution:
    def isBalanced(self, root) -> bool:
        def height(root):
            if not root: return 0
            nonlocal ret
            left_subtree_height = height(root.left)
            right_subtree_height = height(root.right)
            if abs(left_subtree_height - right_subtree_height) > 1:
                ret = False
            return max(left_subtree_height, right_subtree_height) + 1

        ret = True
        height(root)
        return ret


if __name__ == '__main__':
    s = Solution()
    root = [3, 9, 20, None, None, 15, 7]
    print('1', s.isBalanced(create_treenode(root)))
    root = [1, 2, 2, 3, 3, None, None, 4, 4]
    # print(create_treenode(root))
    print('1', s.isBalanced(create_treenode(root)))
    root = []
    print('1', s.isBalanced(create_treenode(root)))
Example #8
0
     3   6
    / \
   2   4
  /
 1
输出: 4
限制:
1 ≤ k ≤ 二叉搜索树元素个数
'''


class Solution:
    def kthLargest(self, root, k: int) -> int:
        def inorder(node):
            if not node:
                return []
            return inorder(node.left) + [node.value] + inorder(node.right)

        return inorder(root)[-k]


if __name__ == '__main__':
    s = Solution()
    from src.common.tree import create_treenode
    root = create_treenode([3, 1, 4, None, 2])
    k = 1
    print(s.kthLargest(root, k))
    root = create_treenode([5, 3, 6, 2, 4, None, None, 1])
    k = 3
    print(s.kthLargest(root, k))
Example #9
0
                    node.right = Node(val)
                    break
                else:
                    node = node.right
        return root

    def insertIntoBST2(self, root, val: int):  #递归
        #世间法复杂度O(n) 空间复杂度O(n)
        if not root: return Node(val)
        if root.value < val:
            root.right = self.insertIntoBST2(root.right, val)
        else:
            root.left = self.insertIntoBST2(root.left, val)
        return root


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([4, 2, 7, 1, 3])
    val = 5
    print(root)
    print('1', s.insertIntoBST(root, val))
    root = create_treenode([4, 2, 7, 1, 3])
    print('2', s.insertIntoBST2(root, val))
    root = create_treenode([40, 20, 60, 10, 30, 50, 70])
    val = 25
    print(root)
    print('1', s.insertIntoBST(root, val))
    root = create_treenode([40, 20, 60, 10, 30, 50, 70])
    print('2', s.insertIntoBST2(root, val))
            q.append(a.left)
            q.append(b.right)

            q.append(a.right)
            q.append(b.left)
        return True
    def isSymmetric2(self, root) -> bool:
        if not root:return False
        def dfs(lnode,rnode):
            if not lnode and rnode:return False
            if not rnode and lnode:return False
            if not lnode and not rnode:return True
            return (lnode.value == rnode.value) and dfs(lnode.left, rnode.right) and dfs(lnode.right, rnode.left)
        return dfs(root.left,root.right)
if __name__ =='__main__':
    s =Solution()
    root = create_treenode([1, 2, 2, 3, 4, 4, 3])
    print(root)
    print('1',s.isSymmetric(root))
    print('2',s.isSymmetric2(root))
    root = create_treenode([1, 2, 2, None, 3, None, 3])
    print(root)
    print('1',s.isSymmetric(root))
    root = create_treenode([1, 2])
    print(root)
    print('1',s.isSymmetric(root))
    root = create_treenode(
        [2, 3, 3, 4, 5, 5, 4, None, None, 8, 9, None, None, 9, 8])
    print(root)
    print('1',s.isSymmetric(root))
树中将会有 1 到 100 个结点。

'''
from src.common.tree import create_treenode


class Solution:
    def isCompleteTree(self, root) -> bool:
        if not root: return False
        nodes = [(root, 1)]
        i = 0
        while i < len(nodes):
            node, v = nodes[i]
            i += 1
            if node.left:
                nodes.append((node.left, 2 * v))
            if node.right:
                nodes.append((node.right, 2 * v + 1))
        return nodes[-1][1] == len(nodes)


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([1, 2, 3])
    print(root)
    print('1', s.isCompleteTree(root))
    root = create_treenode([1, 2, 3, 4, 5, None, 7])
    print(root)
    print('1', s.isCompleteTree(root))
Example #12
0
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
'''

from src.common.tree import create_treenode


class Solution:
    def postorderTraversal(self, root):
        if not root: return []
        return self.postorderTraversal(root.left) + self.postorderTraversal(
            root.right) + [root.value]

    def postorderTraversal2(self, root):
        stack = [root]
        ret = []
        while stack:
            node = stack.pop()
            if node:
                ret.append(node.value)
                stack.append(node.left)
                stack.append(node.right)
        return ret[::-1]


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([1, None, 2, None, None, 3])
    print(root)
    print('1', s.postorderTraversal(root))
    print('2', s.postorderTraversal2(root))
Example #13
0
解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
'''


class Solution:
    def binaryTreePaths(self, root):
        if not root: return []

        def dfs(node, path):
            if not node: return
            path += str(node.value)
            if not node.left and not node.right:
                paths.append(path)
            else:
                path += '->'
                dfs(node.left, path)
                dfs(node.right, path)

        paths = []
        dfs(root, '')
        return paths


if __name__ == '__main__':
    s = Solution()
    from src.common.tree import create_treenode
    root = create_treenode([1, 2, 3, None, 5])
    print(root)
    print('1', s.binaryTreePaths(root))
1   3 6   9
输出:

     4
   /   \
  7     2
 / \   / \
9   6 3   1
备注:
这个问题是受到 Max Howell 的 原问题 启发的 :

谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。
'''


class Solution:
    def invertTree(self, root):
        if not root: return None
        left = self.invertTree(root.left)
        right = self.invertTree(root.right)
        root.left, root.right = right, left
        return root


if __name__ == '__main__':
    s = Solution()
    from src.common.tree import create_treenode
    root = create_treenode([4, 2, 7, 1, 3, 6, 9])
    print(root)
    print('1', s.invertTree(root))
Example #15
0
                node = q.popleft()
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
        return ret


    def rightSideView_dfs(self, root):
        if not root:return []
        stack,ret =[(root,0)],dict()
        while stack:
            node,depth = stack.pop()
            if node:
                #setdefault已经存在的key,就不会重复插入
                ret.setdefault(depth, node.value)
                stack.append((node.left,depth+1))
                stack.append((node.right,depth+1))
        return [val for _,val in ret.items()]

if __name__ == '__main__':
    s = Solution()
    root = create_treenode([1, 2, 3, None, 5, None, 4])
    print('bfs', s.rightSideView_bfs(root))
    print('dfs', s.rightSideView_dfs(root))
    # print('pre-order', root.preorder)
    root = create_treenode([1, 2])
    print(root)
    print('bfs', s.rightSideView_bfs(root))
    print('dfs', s.rightSideView_dfs(root))
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:2
示例 2:
输入:root = [2,null,3,null,4,null,5,null,6]
输出:5
'''
from src.common.tree import create_treenode


class Solution:
    def minDepth(self, root) -> int:
        if not root: return 0
        left_depth = self.minDepth(root.left)
        right_depth = self.minDepth(root.right)
        return left_depth + right_depth + 1 if (
            left_depth == 0
            or right_depth == 0) else min(left_depth, right_depth) + 1

    def maxDepth(self, root) -> int:
        if not root: return 0
        return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1


if __name__ == "__main__":
    s = Solution()
    l = [3, 9, 20, None, None, 15, 7]
    t = create_treenode(l)
    print(t)
    print('1', s.minDepth(t))
    print('2', s.maxDepth(t))
Example #17
0

class Solution:
    def longestUnivaluePath(self, root) -> int:
        def dfs(node):
            if not node:
                return 0
            left_height = dfs(node.left)
            right_height = dfs(node.right)
            a, b = 0, 0
            if node.left and node.value == node.left.value:
                a = left_height + 1
            if node.right and node.value == node.right.value:
                b = right_height + 1
            self.max_path = max(self.max_path, a + b)
            return max(a, b)

        self.max_path = 0
        dfs(root)
        return self.max_path


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([5, 4, 5, 1, 1, None, 5])
    print(root)
    print('1', s.longestUnivaluePath(root))
    root = create_treenode([1, 4, 5, 4, 4, None, 5])
    print(root)
    print('1', s.longestUnivaluePath(root))
        return self.inorderTraversal(
            root.left) + [root.value] + self.inorderTraversal(root.right)

    def inorderTraversal2(self, root):
        stack = []
        node = root
        ret = []
        while stack or node:
            while node:
                stack.append(node)
                node = node.left
            if stack:
                node = stack.pop()
                ret.append(node.value)
                node = node.right
        return ret


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([1, None, 2, None, None, 3])
    print('1', s.inorderTraversal(root))
    root = create_treenode([])
    print('1', s.inorderTraversal(root))
    root = create_treenode([1, 2])
    print('1', s.inorderTraversal(root))
    root = create_treenode([1])
    print('1', s.inorderTraversal(root))
    root = create_treenode([1, None, 2])
    print('1', s.inorderTraversal(root))

class Solution:
    def maxPathSum(self, root) -> int:
        def maxGain(node):
            if not node:
                return 0
            left_gain = max(maxGain(node.left), 0)
            righ_gain = max(maxGain(node.right), 0)
            price_new_path = node.value + righ_gain + left_gain
            self.max_gain = max(self.max_gain, price_new_path)
            return node.value + max(left_gain, righ_gain)

        #时间复杂度O(n) 空间复杂度O(n)
        self.max_gain = float('-inf')
        maxGain(root)
        return self.max_gain


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([1, 2, 3])
    print(root)
    print('1', s.maxPathSum(root))
    root = create_treenode([-10, 9, 20, None, None, 15, 7])
    print(root)
    print('1', s.maxPathSum(root))
    root = create_treenode([-3])
    print(root)
    print('1', s.maxPathSum(root))
                return -1
            elif node == target:
                subtree_add(node,0)
                return 1
            else:
                l,r=dfs(node.left),dfs(node.right)
                if l !=-1:
                    if l==K:ret.append(node.value)
                    subtree_add(node.right,l+1)
                    return l+1
                elif r !=-1:
                    if r == K: ret.append(node.value)
                    subtree_add(node.left,r+1)
                    return r+1
                else:
                    return -1
        dfs(root)
        return ret
            
            
if __name__ =='__main__':
    s = Solution()
    from src.common.tree import create_treenode
    root = create_treenode([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4])
    target = root[1]
    K = 2
    print(root,target)
    #[7, 4, 1]
    print('1', s.distanceK(root, target, K))
    print('2', s.distanceK2(root, target, K))
Example #21
0
    def pathSum_dfs(self, root, targetSum: int):
        if not root: return []

        # 时间复杂度O(n) 空间复杂度O(n)
        def dfs(root, targetSum):
            if not root:
                return
            path.append(root.value)
            targetSum -= root.value
            if not root.left and not root.right and targetSum == 0:
                ret.append(path[:])
            dfs(root.left, targetSum)
            dfs(root.right, targetSum)
            path.pop()

        ret = []
        path = []
        dfs(root, targetSum)
        return ret


if __name__ == '__main__':
    s = Solution()
    root = create_treenode(
        [5, 4, 8, 11, None, 13, 4, 7, 2, None, None, None, None, 5, 1])
    print(root)
    ts = 22
    print('1', s.pathSum_bfs(root, ts))
    print('1', s.pathSum_dfs(root, ts))
class Solution:
    def preorderTraversal1(self, root):  #递归
        if not root:
            return []
        l = self.preorderTraversal1(root.left)
        r = self.preorderTraversal1(root.right)
        return [root.value] + l + r

    def preorderTraversal2(self, root):  #迭代
        if not root:
            return []
        stack, ret = [root], []
        while stack:
            node = stack.pop()
            if node:
                ret.append(node.value)
                stack.append(node.right)
                stack.append(node.left)
        return ret


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([1, None, 2, None, None, 3])
    print(root)
    print('1', s.preorderTraversal1(root))
    print('2', s.preorderTraversal2(root))
    root = create_treenode([1, 2, 3, 4, None, 5])
    print('1', s.preorderTraversal1(root))
    print('2', s.preorderTraversal2(root))
            r_height = dfs(root.right)
            self.max_ret = max(self.max_ret, r_height + l_height + 1)
            return max(l_height, r_height) + 1

        self.max_ret = 1  #最大节点数
        dfs(root)
        return self.max_ret - 1

    def diameterOfBinaryTree2(self, root) -> int:
        diameter = 0

        def height(node):
            if not node:
                return 0
            nonlocal diameter
            lheight = height(node.left)
            rheight = height(node.right)
            diameter = max(lheight + rheight, diameter)
            return max(lheight, rheight) + 1

        height(root)
        return diameter


if __name__ == '__main__':
    s = Solution()
    root = create_treenode([1, 2, 3, 4, 5])
    print(root)
    print('1', s.diameterOfBinaryTree(root))
    print('2', s.diameterOfBinaryTree2(root))
            _, end = q[-1]
            for _ in range(len(q)):
                node, v = q.popleft()
                if node.left:
                    q.append((node.left, 2 * v))
                if node.right:
                    q.append((node.right, 2 * v + 1))
            print(q)
            max_width = max(max_width, end - start + 1)
        return max_width


if __name__ == '__main__':
    s = Solution()
    from src.common.tree import create_treenode
    root = create_treenode([1, 3, 2, 5, 3, None, 9])
    print(root)
    print('1', s.widthOfBinaryTree(root))
    print('2', s.widthOfBinaryTree2(root))
    root = create_treenode([1, 3, None, 5, 3])
    print(root)
    print('1', s.widthOfBinaryTree(root))
    print('2', s.widthOfBinaryTree2(root))
    root = create_treenode([1, 3, 2, 5, None])
    print(root)
    print('1', s.widthOfBinaryTree(root))
    print('2', s.widthOfBinaryTree2(root))
    root = create_treenode(
        [1, 3, 2, 5, None, None, 9, 6, None, None, None, None, None, None, 7])
    print(root)
    print('1', s.widthOfBinaryTree(root))
Example #25
0
    def isValidBST4(self, root) -> bool:  # 迭代中序遍历
        stack = []
        node = root
        inorder = float('-inf')
        #O(n*n)
        while stack or node:
            while node:
                stack.append(node)
                node = node.left
            node = stack.pop()
            if node.value <= inorder:
                return False
            inorder = node.value
            node = node.right
        return True


if __name__ == "__main__":
    tree_node = create_treenode([2, 1, 3])
    s = Solution()
    print('1', s.isValidBST1(tree_node))
    print('2', s.isValidBST2(tree_node))
    print('3', s.isValidBST3(tree_node))
    print('4', s.isValidBST4(tree_node))
    tree_node = create_treenode([5, 1, 4, None, None, 3, 6])
    print('1', s.isValidBST1(tree_node))
    print('2', s.isValidBST2(tree_node))
    print('3', s.isValidBST3(tree_node))
    print('4', s.isValidBST4(tree_node))