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)))
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)))
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)
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)
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))
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)))
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))
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)))
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))
""" 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))
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)
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)
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)
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)
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)
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())
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))
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)))
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))
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))
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)
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))
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)))
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)))
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)