Ejemplo n.º 1
0
from util import lc_list2tree, TreeNode


class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        q = collections.deque()
        q.append(root)
        while q:
            l = len(q)
            cmp = []
            for _ in range(l):
                cur = q.popleft()
                if cur:
                    cmp.append(cur.val)
                    q.append(cur.left)
                    q.append(cur.right)
                else:
                    cmp.append(None)
            mid = len(cmp) // 2
            if cmp[:mid] != cmp[len(cmp) - 1:mid - 1:-1]:
                return False
        return True


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[1, 2, 2, 3, 4, 4, 3], [1, 2, 2, None, 3, None, 3],
                  [1, 2, 2, 3, 4, 4, 3, None, 5, None, None, None, None, 5]]
    for i in test_cases:
        print(sol.isSymmetric(lc_list2tree(i)))
Ejemplo n.º 2
0
        if root.val == key:
            if not root.left:
                return root.right
            if not root.right:
                return root.left
            new_root = root.left
            while new_root.right:
                new_root = new_root.right
            root.val, new_root.val = new_root.val, root.val
            root.left = self.deleteNode(root.left, key)
        elif root.val > key:
            root.left = self.deleteNode(root.left, key)
        else:
            root.right = self.deleteNode(root.right, key)
        return root


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [[5, 3, 6, 2, 4, None, 7], 3],
        [[5, 3, 6, 2, 4, None, 7], 0],
        [[5, 3, 6, 2, 4, None, 7], 7],
        [[5, 3, 6, 2, 4, None, 7], 5],
    ]
    for i, j in test_cases:
        result = sol.deleteNode(lc_list2tree(i), j)
        print(lc_tree2list(result))


from collections import defaultdict
from util import lc_list2tree, TreeNode, lc_tree2list


class Solution:
    def getMinimumDifference(self, root: TreeNode) -> int:
        minn = math.inf
        pre = -math.inf

        def inorder(node):
            nonlocal pre, minn
            if node:
                inorder(node.left)
                minn = min(minn, node.val - pre)
                pre = node.val
                inorder(node.right)
                return node.val
            return None

        inorder(root)
        return minn


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[4, 2, 6, 1, 3], [1, 0, 48, None, None, 12, 49],
                  [236, 104, 701, None, 227, None, 911]]
    for i in test_cases:
        result = sol.getMinimumDifference(lc_list2tree(i))
        print(result)
from collections import deque
from util import (ListNode, lc_list2singlelinkedlist, lc_singlelinkedlist2list,
                  TreeNode, lc_tree2list, lc_list2tree)


class Solution:
    def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []
        q = deque([root])
        ans = []
        while q:
            l = len(q)
            ans.append([])
            for _ in range(l):
                cur = q.popleft()
                ans[-1].append(cur.val)
                if cur.left:
                    q.append(cur.left)
                if cur.right:
                    q.append(cur.right)
        ans.reverse()
        return ans


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[3, 9, 20, None, None, 15, 7], [1], []]
    for i in test_cases:
        print(sol.levelOrderBottom(lc_list2tree(i)))
Ejemplo n.º 5
0
import collections
import math
from typing import List
from collections import defaultdict
from util import lc_list2tree, TreeNode, lc_tree2list


class Solution:
    def findBottomLeftValue(self, root: TreeNode) -> int:
        q = collections.deque([root])
        ans = 0
        while q:
            l = len(q)
            for i in range(l):
                cur = q.popleft()
                ans = cur.val
                if cur.right:
                    q.append(cur.right)
                if cur.left:
                    q.append(cur.left)
        return ans


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[3, 9, 20, None, None, 15, 7],
                  [1, 2, 3, 4, None, 5, 6, None, None, 7]]
    for i in test_cases:
        result = sol.findBottomLeftValue(lc_list2tree(i))
        print(result)
Ejemplo n.º 6
0
class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        ans = []
        stack = [root]
        while stack:
            cur = stack.pop()
            if cur:
                ans.append(cur.val)
                stack.append(cur.left)
                stack.append(cur.right)
        return ans[::-1]

        # def postorder(node):
        #     if node:
        #         postorder(node.left)
        #         postorder(node.right)
        #         ans.append(node.val)
        #
        # postorder(root)
        # return ans


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[1, 2, 3, 4, 5, 6, 7], [1, None, 2, 3],
                  [1, 2, 3, None, 4, None, 5]]
    for i in test_cases:
        result = sol.postorderTraversal(lc_list2tree(i))
        print(result)
Ejemplo n.º 7
0
import bisect
import collections
import math
import re
from typing import List
from util import TreeNode, lc_list2tree


class Solution:
    def binaryTreePaths(self, root: TreeNode) -> List[str]:
        ans = []

        def dfs(node, s):
            if node:
                s += f'->{node.val}'
                if not node.left and not node.right:
                    ans.append(s[2:])
                dfs(node.left, s)
                dfs(node.right, s)

        dfs(root, '')
        return ans


if __name__ == "__main__":
    root = [1, 2, 3, None, 5]
    root = lc_list2tree(root)
    sol = Solution()
    print(sol.binaryTreePaths(root))
import collections
import math
from typing import List
from collections import defaultdict
from util import lc_list2tree, TreeNode, lc_tree2list


class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode',
                             q: 'TreeNode') -> 'TreeNode':
        if p.val > q.val:
            p, q = q, p
        if p.val <= root.val <= q.val:
            return root
        if q.val < root.val:
            return self.lowestCommonAncestor(root.left, p, q)
        elif p.val > root.val:
            return self.lowestCommonAncestor(root.right, p, q)


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [[6, 2, 8, 0, 4, 7, 9, None, None, 3, 5], [2], [8]],
        [[6, 2, 8, 0, 4, 7, 9, None, None, 3, 5], [2], [4]],
    ]
    for i, p, q in test_cases:
        result = sol.lowestCommonAncestor(lc_list2tree(i), lc_list2tree(p),
                                          lc_list2tree(q))
        print(lc_tree2list(result))
Ejemplo n.º 9
0
        rtn = 0
        if not root or (not root.left and not root.right):
            return 0

        def helper(node):
            nonlocal rtn
            if not node:
                return 0
            if not node.left and not node.right:
                return 1
            left = helper(node.left)
            right = helper(node.right)
            rtn = max(rtn, left + right)
            return max(left, right) + 1

        helper(root)
        return rtn


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [3, 9, 20, None, None, 15, 7],
        [1, None, 2],
        [1, 2, None, 3, None],
        [1],
        [2, 1, 4, 3, None, 5],
    ]
    for i in test_cases:
        print(sol.diameterOfBinaryTree(lc_list2tree(i)))
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        ans = []
        stack = [root]
        while stack:
            cur = stack.pop()
            if cur:
                ans.append(cur.val)
                stack.append(cur.right)
                stack.append(cur.left)
        return ans

        # def helper(node):
        #     if node:
        #         ans.append(node.val)
        #         helper(node.left)
        #         helper(node.right)
        #
        # helper(root)
        # return ans


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [1, None, 2, 3],
        [3, 9, 20, None, 15, 7],
    ]
    for i in test_cases:
        print(sol.preorderTraversal(lc_list2tree(i)))
Ejemplo n.º 11
0
import collections
import math
from typing import List
from collections import defaultdict
from util import lc_list2tree, TreeNode, lc_tree2list


class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        stack = [root]
        while stack:
            cur = stack.pop()
            if cur:
                cur.left, cur.right = cur.right, cur.left
                stack += cur.left, cur.right
        return root
        # if not root:
        #     return None
        # root.left, root.right = root.right, root.left
        # self.invertTree(root.left)
        # self.invertTree(root.right)
        # return root


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[4, 2, 7, 1, 3, 6, 9], [2, 1, 3]]
    for i in test_cases:
        result = sol.invertTree(lc_list2tree(i))
        print(lc_tree2list(result))
Ejemplo n.º 12
0

class Solution:
    def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []
        q = deque([root])
        ans = []
        reverse = False
        while q:
            l = len(q)
            ans.append([])
            for _ in range(l):
                cur = q.popleft()
                ans[-1].append(cur.val)
                if cur.left:
                    q.append(cur.left)
                if cur.right:
                    q.append(cur.right)
            if reverse:
                ans[-1].reverse()
            reverse = not reverse
        return ans


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[3, 9, 20, None, None, 15, 7], [1], []]
    for i in test_cases:
        print(sol.zigzagLevelOrder(lc_list2tree(i)))
Ejemplo n.º 13
0
from util import lc_list2tree, TreeNode, lc_tree2list, lc_list2singlelinkedlist, ListNode


class Solution:
    def increasingBST(self, root: TreeNode) -> TreeNode:
        rtn = cur = TreeNode()

        def inorder(node):
            nonlocal cur
            if node:
                inorder(node.left)
                cur.right = TreeNode(node.val)
                cur = cur.right
                inorder(node.right)

        inorder(root)
        return rtn.right


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [5, 3, 6, 2, 4, None, 8, 1, None, None, None, 7, 9],
        [5, 1, 7],
    ]
    for i in test_cases:
        result = sol.increasingBST(lc_list2tree(i))
        print(lc_tree2list(result))


Ejemplo n.º 14
0
        """
        Do not return anything, modify root in-place instead.
        """
        pre = None
        m1 = m2 = None

        def inorder(node):
            nonlocal pre, m1, m2
            if node:
                inorder(node.left)
                if pre and node.val < pre.val:
                    if not m1:
                        m1 = pre
                        m2 = node
                    else:
                        m2 = node
                pre = node
                inorder(node.right)

        inorder(root)
        m1.val, m2.val = m2.val, m1.val
        return root


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[50, 17, 76, 54, 23, 9], [3, 1, 4, None, None, 2]]
    for i in test_cases:
        result = (sol.recoverTree(lc_list2tree(i)))
        print(lc_tree2list(result))
Ejemplo n.º 15
0
class Solution:
    def findTarget(self, root: TreeNode, k: int) -> bool:
        sorted_l = []

        def inorder(node):
            if not node:
                return
            inorder(node.left)
            sorted_l.append(node.val)
            inorder(node.right)

        inorder(root)
        l, r = 0, len(sorted_l) - 1
        while l < r:
            if sorted_l[l] + sorted_l[r] == k:
                return True
            if sorted_l[l] + sorted_l[r] > k:
                r -= 1
            if sorted_l[l] + sorted_l[r] < k:
                l += 1
        return False


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[[5, 3, 6, 2, 4, None, 7], 9], [[5, 3, 6, 2, 4, None, 7],
                                                  28], [[1], 2]]
    for i, j in test_cases:
        result = sol.findTarget(lc_list2tree(i), j)
        print(result)
Ejemplo n.º 16
0
import bisect
from copy import deepcopy
from typing import List, Optional
from collections import defaultdict
from util import (ListNode, lc_list2singlelinkedlist, lc_singlelinkedlist2list,
                  TreeNode, lc_tree2list, lc_list2tree)


class Solution:
    def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
        def check_node(n1, n2):
            if n1 and n2 and n1.val == n2.val or not n1 and not n2:
                if not n1 and not n2 or not n1.left and not n1.right and not n2.left and not n2.right:
                    return True
                return check_node(n1.left, n2.left) and check_node(
                    n1.right, n2.right)
            return False

        return check_node(p, q)


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[[1, 2, 3], [1, 2, 3]], [[1, 2], [1, None, 2]],
                  [[1, 2, 1], [1, 1, 2]], [[], []]]
    for i, j in test_cases:
        result = sol.isSameTree(lc_list2tree(i), lc_list2tree(j))
        print(result)
Ejemplo n.º 17
0
        if not root:
            return 0
        q = collections.deque([root])
        lv = 1
        end_flag = False
        while q:
            for _ in range(len(q)):
                cur = q.popleft()
                if not cur.left and not cur.right:
                    end_flag = True
                if cur.left:
                    q.append(cur.left)
                if cur.right:
                    q.append(cur.right)
            if end_flag:
                break
            lv += 1
        return lv


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [3, 9, 20, None, None, 15, 7],
        [2, None, 3, None, 4, None, 5, None, 6],
    ]
    for i in test_cases:
        result = sol.minDepth(lc_list2tree(i))
        print(result)

Ejemplo n.º 18
0
            if node.left:
                cur_node.left = dfs(node.left, cur_node)
            if node.right:
                cur_node.right = dfs(node.right, cur_node)
            return cur_node

        def prepare_ans(node):
            tmp = []
            while node:
                if node.parent:
                    tmp.append(node.val - node.parent.val)
                else:
                    tmp.append(node.val)
                node = node.parent
            tmp.reverse()
            ans.append(tmp)
        dfs(root, None)
        return ans


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [[5,4,8,11,None,13,4,7,2,None,None,5,1], 22],
        [[1,2,3], 5],
    ]
    for i, j in test_cases:
        result = sol.pathSum(lc_list2tree(i), j)
        print(result)

Ejemplo n.º 19
0
class Solution:
    def same_tree(self, node, subnode):
        if not node and not subnode:
            return True
        if not node or not subnode:
            return False
        if subnode.val == node.val:
            return self.same_tree(node.left, subnode.left) and self.same_tree(
                node.right, subnode.right)
        return False

    def isSubtree(self, root: TreeNode, subRoot: TreeNode) -> bool:
        if not root:
            return False
        if self.same_tree(root, subRoot):
            return True
        return self.isSubtree(root.left, subRoot) or self.isSubtree(
            root.right, subRoot)


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [[3, 4, 5, 1, 2], [4, 1, 2]],
        [[3, 4, 5, 1, 2, None, None, None, None, 0], [4, 1, 2]],
        [[1, None, 1, None, 1, None, 1, 2], [1, None, 1, 2]],
    ]
    for i, j in test_cases:
        result = sol.isSubtree(lc_list2tree(i), lc_list2tree(j))
        print(result)
Ejemplo n.º 20
0
        self.inorder_trav(root)

    def inorder_trav(self, root):
        if root:
            self.inorder_trav(root.left)
            self.q.append(root.val)
            self.inorder_trav(root.right)

    def next(self) -> int:
        rtn = self.q[self.idx]
        self.idx += 1
        return rtn

    def hasNext(self) -> bool:
        return self.idx < len(self.q)


if __name__ == "__main__":
    cmd = [
        "BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next",
        "hasNext", "next", "hasNext"
    ]
    val = [[[7, 3, 15, None, None, 9, 20]], [], [], [], [], [], [], [], [], []]
    for idx, i in enumerate(cmd):
        if i == "BSTIterator":
            bst = BSTIterator(lc_list2tree(val[0][0]))
        elif i == "next":
            print(bst.next())
        elif i == "hasNext":
            print(bst.hasNext())
Ejemplo n.º 21
0
        def find_leaves(node: TreeNode) -> None:
            if node:
                find_leaves(node.left)
                find_leaves(node.right)
                if not (node.left or node.right):
                    self.leaves += str(node.val) + ','

        find_leaves(root1)
        l1 = self.leaves
        self.leaves = ''
        find_leaves(root2)
        return l1 == self.leaves


if __name__ == "__main__":
    sol = Solution()
    root1 = [3, 5, 1, 6, 2, 9, 8, None, None, 7, 4]
    root2 = [3, 5, 1, 6, 7, 4, 2, None, None, None, None, None, None, 9, 8]
    root1 = [1]
    root2 = [1]
    root1 = [1]
    root2 = [2]
    root1 = [1, 2, 3]
    root2 = [1, 3, 2]
    root1 = [3, 5, 1, 6, 2, 9, 8, None, None, 7, 14]
    root2 = [3, 5, 1, 6, 71, 4, 2, None, None, None, None, None, None, 9, 8]
    root1 = lc_list2tree(root1)
    root2 = lc_list2tree(root2)
    print(sol.leafSimilar(root1, root2))
Ejemplo n.º 22
0
from typing import List, Optional
from collections import deque
from util import (ListNode, lc_list2singlelinkedlist, lc_singlelinkedlist2list,
                  TreeNode, lc_tree2list, lc_list2tree)


class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []
        q = deque([root])
        ans = []
        while q:
            l = len(q)
            ans.append([])
            for _ in range(l):
                cur = q.popleft()
                ans[-1].append(cur.val)
                if cur.left:
                    q.append(cur.left)
                if cur.right:
                    q.append(cur.right)
        return ans


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[3, 9, 20, None, None, 15, 7], [1], []]
    for i in test_cases:
        print(sol.levelOrder(lc_list2tree(i)))
Ejemplo n.º 23
0
import collections
import math
from typing import List
from collections import defaultdict
from util import lc_list2tree, TreeNode, lc_tree2list


class Solution:
    def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
        if not root1 and not root2:
            return None
        new_tree = TreeNode(0)
        n1 = root1 if root1 else TreeNode(0)
        n2 = root2 if root2 else TreeNode(0)
        new_tree.val = n1.val + n2.val
        new_tree.left = self.mergeTrees(n1.left, n2.left)
        new_tree.right = self.mergeTrees(n1.right, n2.right)
        return new_tree


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [[1, 3, 2, 5], [2, 1, 3, None, 4, None, 7]],
        [[1], [1, 2]],
    ]
    for i, j in test_cases:
        result = sol.mergeTrees(lc_list2tree(i), lc_list2tree(j))
        print(lc_tree2list(result))
Ejemplo n.º 24
0
            return node

        inverted_inorder(root)
        return root

        # def inverted_inorder(node, pre):
        #     if not node:
        #         return 0
        #     if node.right:
        #         pre = inverted_inorder(node.right, pre)
        #     node.val += pre
        #     left = 0
        #     if node.left:
        #         left = inverted_inorder(node.left, node.val)
        #     return left if left else node.val
        #
        # inverted_inorder(root, 0)
        # return root


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [4, 1, 6, 0, 2, 5, 7, None, None, None, 3, None, None, None, 8],
        [3, 2, 4, 1],
    ]
    for i in test_cases:
        result = sol.convertBST(lc_list2tree(i))
        print(lc_tree2list(result))

Ejemplo n.º 25
0
import math
from typing import List
from collections import defaultdict
from util import lc_list2tree, TreeNode, lc_tree2list


class Solution:
    def sumOfLeftLeaves(self, root: TreeNode) -> int:
        ans = 0

        def preorder(node, left):
            nonlocal ans
            if node:
                if not node.left and not node.right and left:
                    ans += node.val
                preorder(node.left, True)
                preorder(node.right, False)

        preorder(root, False)
        return ans


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [3, 9, 20, None, None, 15, 7],
    ]
    for i in test_cases:
        result = sol.sumOfLeftLeaves(lc_list2tree(i))
        print(result)
Ejemplo n.º 26
0
        if not root:
            return []
        ans = []
        stack = []
        cur = root
        while cur or stack:
            while cur:
                stack.append(cur)
                cur = cur.left
            cur = stack.pop()
            ans.append(cur.val)
            cur = cur.right
        return ans

        # def inorder(node):
        #     if node:
        #         inorder(node.left)
        #         ans.append(node.val)
        #         inorder(node.right)
        #
        # inorder(root)
        # return ans


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[1, None, 2, 3], [1, 2, 3, None, 4, None, 5]]
    for i in test_cases:
        result = sol.inorderTraversal(lc_list2tree(i))
        print(result)
        if not root:
            return

        def po(node):
            if not node or not node.left and not node.right:
                return node
            right = tmp = po(node.left)
            if right:
                while tmp.right:
                    tmp = tmp.right
                tmp.right = po(node.right)
                node.left = None
                node.right = right
            else:
                po(node.right)
            return node

        po(root)


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [1, 2, 5, 3, 4, None, 6],
        [],
        [0]
    ]
    for i in test_cases:
        sol.flatten(lc_list2tree(i))

Ejemplo n.º 28
0
class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        q = collections.deque()
        q.append(root)
        cnt = 0
        while q:
            cnt += 1
            l = len(q)
            for _ in range(l):
                cur_root = q.popleft()
                if cur_root.left:
                    q.append(cur_root.left)
                if cur_root.right:
                    q.append(cur_root.right)
        return cnt


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [3, 9, 20, None, None, 15, 7],
        [1, None, 2],
        [],
        [1],
    ]
    for i in test_cases:
        print(sol.maxDepth(lc_list2tree(i)))
Ejemplo n.º 29
0
from util import TreeNode, lc_tree2list, lc_list2tree


class Solution:
    def sumNumbers(self, root: Optional[TreeNode]) -> int:
        ans = 0

        def po(node, cur):
            nonlocal ans
            cur += str(node.val)
            if not node.left and not node.right:
                ans += int(cur)
                return
            if node.left:
                po(node.left, cur)
            if node.right:
                po(node.right, cur)

        po(root, '')
        return ans


if __name__ == "__main__":
    sol = Solution()
    test_cases = [
        [1, 2, 3],
        [4, 9, 0, 5, 1],
    ]
    for i in test_cases:
        print(sol.sumNumbers(lc_list2tree(i)))
Ejemplo n.º 30
0
from copy import deepcopy
from typing import List, Optional
from collections import defaultdict
from util import (ListNode, lc_list2singlelinkedlist, lc_singlelinkedlist2list,
                  TreeNode, lc_tree2list, lc_list2tree)


class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        nodes = []

        def inorder(node):
            left = right = True
            if node:
                left = inorder(node.left)
                if nodes and node.val <= nodes[-1]:
                    return False
                nodes.append(node.val)
                right = inorder(node.right)
            return left and right

        return inorder(root)


if __name__ == "__main__":
    sol = Solution()
    test_cases = [[2, 1, 3], [5, 1, 4, None, None, 3, 6], [2, 2, 2]]
    for i in test_cases:
        result = sol.isValidBST(lc_list2tree(i))
        print(result)