def helper(node): if not node: return None left = helper(node.left) right = helper(node.right) if not left and not right: return node elif not left: return right elif not right: node.right = node.left node.left = None return left left.right = node.right node.right = node.left node.left = None return right helper(root) return root if __name__ == "__main__": root = constructBinaryTree([1, 2, 5, 3, 4, null, 6]) root.prettyPrint() #node = Solution().flatten(root) node = Solution().flattenClean(root) while node: assert node.left is None print(node.val, '->', end='') node = node.right print()
:rtype: bool """ stack = [] s = set() while stack or root1: while root1: stack.append(root1) root1 = root1.left root1 = stack.pop() s.add(target - root1.val) root1 = root1.right while stack or root2: while root2: stack.append(root2) root2 = root2.left root2 = stack.pop() if root2.val in s: return True root2 = root2.right return False if __name__ == "__main__": root1 = constructBinaryTree([2, 1, 4]) root2 = constructBinaryTree([1, 0, 3]) print(Solution().twoSumBSTs(root1, root2, 5)) print(Solution().twoSumBSTsIterative(root1, root2, 5)) root1 = constructBinaryTree([0, -10, 10]) root2 = constructBinaryTree([5, 1, 7, 0, 2]) print(Solution().twoSumBSTs(root1, root2, 18)) print(Solution().twoSumBSTsIterative(root1, root2, 18))
class Solution(object): def findDistance(self, root, p, q): def LCA(node, p, q): if not node: return None if node.val == p or node.val == q: return node (left, right) = (LCA(node.left, p, q), LCA(node.right, p, q)) return root if left and right else left or right def distance(root, v): if not root: return -1 if root.val == v: return 0 left = distance(root.left, v) right = distance(root.right, v) if left >= 0: return left + 1 if right >= 0: return right + 1 return -1 lca = LCA(root, p, q) #return distance(root, p) + distance(root, q) - 2 * distance(root, lca.val) return distance(lca, p) + distance(lca, q) if __name__ == "__main__": root = constructBinaryTree([3, 5, 1, 6, 2, 0, 8, null, null, 7, 4]) root.prettyPrint() print(Solution().findDistance(root, 5, 0)) print(Solution().findDistance(root, 5, 7)) print(Solution().findDistance(root, 5, 5))
return node.val + helper(node.left) + helper(node.right) helper(root) return res[0] def maxProductDP(self, root): """ :type root: TreeNode :rtype: int """ m = set() res = 0 def total(node): if not node: return 0 t = node.val + total(node.left) + total(node.right) m.add(t) return t sm = total(root) for i in m: res = max(res, i * (sm - i)) return res % (10**9 + 7) if __name__ == "__main__": root = constructBinaryTree([1, 2, 3, 4, 5, 6]) root.prettyPrint() #rint(Solution().maxProduct(root)) print(Solution().maxProductDP(root))
# self.val = x # self.left = None # self.right = None from BinaryTree import (TreeNode, null, constructBinaryTree) class Solution(object): def getTargetCopy(self, original, cloned, target): """ :type original: TreeNode :type cloned: TreeNode :type target: TreeNode :rtype: TreeNode """ def helper(origin, copy): if not origin: return None if origin == target: return copy return helper(origin.left, copy.left) or \ helper(origin.right, copy.right) return helper(original, cloned) if __name__ == "__main__": root = constructBinaryTree([7, 4, 3, null, null, 6, 19]) root1 = constructBinaryTree([7, 4, 3, null, null, 6, 19]) root.prettyPrint() res = Solution().getTargetCopy(root, root1, root.right) print(res.val)
# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution: def findFrequentTreeSum(self, root: Optional[TreeNode]) -> List[int]: m = defaultdict(int) def helper(node): if not node: return 0 l = helper(node.left) r = helper(node.right) subsm = l + r + node.val m[subsm] += 1 return subsm helper(root) fr = max(m.values()) return [k for k in m if m[k] == fr] if __name__ == "__main__": root = constructBinaryTree([5, 2, -3]) root.prettyPrint() print(Solution().findFrequentTreeSum(root)) root = constructBinaryTree([5, 2, -5]) root.prettyPrint() print(Solution().findFrequentTreeSum(root))
:rtype: bool """ m = defaultdict(int) def helper(node): # recursively compute sum of the node's val and its subtree if not node: return 0 left = helper(node.left) right = helper(node.right) cur = node.val + left + right m[cur] += 1 return cur sm = helper(root) if sm == 0: return m[0] > 1 # if one subtree has ever had a sum = 1/2 of the total (total is an even number) # we can split this subtree from its parent to statisfy the requirement return sm % 2 == 0 and sm // 2 in m if __name__ == "__main__": root = constructBinaryTree([5, 10, 10, null, null, 2, 3]) root.prettyPrint() print(Solution().checkEqualTree(root)) root = constructBinaryTree([1, 2, 10, null, null, 2, 20]) root.prettyPrint() print(Solution().checkEqualTree(root)) root = constructBinaryTree([0, 1, -1]) root.prettyPrint() print(Solution().checkEqualTree(root))
""" @param root: the given BST @param target: the given target @param k: the given k @return: k values in the BST that are closest to the target """ def closestKValues(self, root, target, k): # write your code here #res = [] res = deque() def inorder(root): if not root: return inorder(root.left) if len(res) < k: res.append(root.val) elif abs(root.val - target) < abs(res[0] - target): res.popleft() res.append(root.val) else: return # if the current node is further away, its right # subtree will be ever further, so no need to go down inorder(root.right) inorder(root) return res if __name__ == "__main__": root = constructBinaryTree([4, 2, 5, 1, 3]) root.prettyPrint() print(Solution().closestKValues(root, 3.710, 2))
left = helper(node.left, '-') right = helper(node.right, '+') sig = str(node.val) + left + right m[sig].append(node) return sign + sig helper(root, '=') for s in m: if len(m[s]) > 1: res.append(m[s][0]) return res if __name__ == "__main__": #''' root = constructBinaryTree( [1, 2, 3, 4, null, 2, 4, null, null, null, null, 4]) root.prettyPrint() res = Solution().findDuplicateSubtrees(root) for r in res: print(r.val) #''' root = constructBinaryTree([2, 1, 1]) root.prettyPrint() res = Solution().findDuplicateSubtrees(root) for r in res: print(r.val) root = constructBinaryTree([2, 2, 2, 3, null, 3, null]) root.prettyPrint() res = Solution().findDuplicateSubtrees(root) for r in res: print(r.val)
self.res = 0 def helper(root): if not root: return CMIN, CMAX li, lx = helper(root.left) ri, rx = helper(root.right) mi = min(li, ri) mx = max(lx, rx) if mi != CMIN: self.res = max(self.res, abs(root.val - mi)) if mx != CMAX: self.res = max(self.res, abs(root.val - mx)) return min(mi, root.val), max(mx, root.val) helper(root) return self.res if __name__ == "__main__": node = constructBinaryTree( [8, 3, 10, 1, 6, null, 14, null, null, 4, 7, null, null, 13, null]) #inOrder(node) #print(Solution().maxAncestorDiff(node)) node = constructBinaryTree([ 1, null, 2, null, null, null, 0, null, null, null, null, null, null, 3, null ]) #inOrder(node) #print(Solution().maxAncestorDiff(node)) node = constructBinaryTree([2, null, 0, null, 4, null, 3, null, 1])
class Solution(object): def insertIntoMaxTree(self, root, val): """ :type root: TreeNode :type val: int :rtype: TreeNode """ def helper(node): if not node: t = TreeNode(val) return t if node.val < val: t = TreeNode(val) t.left = node return t node.right = helper(node.right) return node return helper(root) if __name__ == "__main__": root = constructBinaryTree([4, 1, 3, null, null, 2]) rootB = Solution().insertIntoMaxTree(root, 5) rootB.prettyPrint() root = constructBinaryTree([5, 2, 4, null, 1]) rootB = Solution().insertIntoMaxTree(root, 3) rootB.prettyPrint() root = constructBinaryTree([5, 2, 3, null, 1]) rootB = Solution().insertIntoMaxTree(root, 4) rootB.prettyPrint()
if target == 1: return dfs(node.left, target) + dfs(node.right, target) else: return min( dfs(node.left, 0) + dfs(node.right, 1), dfs(node.left, 1) + dfs(node.right, 0), dfs(node.left, 0) + dfs(node.right, 0)) elif node.val == 4: # ^ if target == 1: return min( dfs(node.left, 1) + dfs(node.right, 0), dfs(node.left, 0) + dfs(node.right, 1)) else: return min( dfs(node.left, 1) + dfs(node.right, 1), dfs(node.left, 0) + dfs(node.right, 0)) elif node.val == 5: # not if target == 1: return min(dfs(node.left, 0), dfs(node.right, 0)) else: return min(dfs(node.left, 1), dfs(node.right, 1)) return dfs(root, 1 if result else 0) if __name__ == "__main__": root = constructBinaryTree([3, 5, 4, 2, null, 1, 1, 1, 0]) print(Solution().minimumFlips(root, True)) root = constructBinaryTree([0]) print(Solution().minimumFlips(root, False))
# self.val = val # self.left = left # self.right = right from BinaryTree import (null, constructBinaryTree, TreeNode) class Solution(object): def sumEvenGrandparent(self, root): """ :type root: TreeNode :rtype: int """ res = [0] def helper(node, par): if not node: return if par and par.val % 2 == 0: if node.left: res[0] += node.left.val if node.right: res[0] += node.right.val helper(node.left, node) helper(node.right, node) helper(root, None) return res[0] if __name__ == "__main__": root = constructBinaryTree( [6, 7, 8, 2, 7, 1, 3, 9, null, 1, 4, null, null, null, 5]) root.prettyPrint() print(Solution().sumEvenGrandparent(root))
from BinaryTree import (null, TreeNode, constructBinaryTree) class Solution: def increasingBST(self, root: TreeNode) -> TreeNode: nodes = [] def helper(node): if not node: return helper(node.left) nodes.append(node) helper(node.right) helper(root) root = nodes[0] cur = root for t in nodes[1:]: cur.left = None cur.right = t cur = t cur.left = None cur.right = None return root if __name__ == "__main__": root = constructBinaryTree( [5, 3, 6, 2, 4, null, 8, 1, null, null, null, null, null, 7, 9]) root.prettyPrint() root = Solution().increasingBST(root) root.prettyPrint()
node = node.right def addLeaves(blist, root): if isLeaf(root): blist.append(root.val) else: if root.left: addLeaves(blist, root.left) if root.right: addLeaves(blist, root.right) addLeaves(boundaryList, root) stack = [] node = root.right while node: if not isLeaf(node): stack.append(node.val) if node.right: node = node.right else: node = node.left while stack: boundaryList.append(stack.pop()) return boundaryList if __name__ == "__main__": root = constructBinaryTree( [1, 2, 3, 4, 5, 6, null, null, null, 7, 8, 9, 10]) root.prettyPrint() print(Solution().boundaryOfBinaryTree(root))
through keys of the hashtable, first x (in default sort order) then y in reversed sort order). for each priority queue, pop it until it is empty. """ m = {} res = [] def dfs(root, x, y): if not root: return heapq.heappush(m.setdefault(x, {}).setdefault(y, []), root.val) dfs(root.left, x - 1, y - 1) dfs(root.right, x + 1, y - 1) dfs(root, 0, 0) for x in sorted(m.keys()): cur = [] for y in sorted(m[x].keys(), reverse=True): while m[x][y]: cur.append(heapq.heappop(m[x][y])) res.append(cur) return res if __name__ == "__main__": root = constructBinaryTree([3, 9, 20, null, null, 15, 7]) root.prettyPrint() print(Solution().verticalTraversal(root)) root = constructBinaryTree([1, 2, 3, 4, 5, 6, 7]) root.prettyPrint() print(Solution().verticalTraversal(root))
# self.right = right from BinaryTree import (null, TreeNode, constructBinaryTree) class Solution(object): def flipMatchVoyage(self, root, voyage): """ :type root: TreeNode :type voyage: List[int] :rtype: List[int] """ res = [] idx = [0] def helper(node): if not node: return True if node.val != voyage[idx[0]]: return False idx[0] += 1 if node.left and node.left.val != voyage[idx[0]]: res.append(node.val) return helper(node.right) and helper(node.left) return helper(node.left) and helper(node.right) return res if helper(root) else [-1] if __name__ == "__main__": root = constructBinaryTree([1, 2, 3]) root.prettyPrint() print(Solution().flipMatchVoyage(root, [1, 3, 2]))
rbst, rmin, rmax, rsum = dfs(node.right) else: rbst, rmin, rmax, rsum = True, MAX, MIN, 0 sums = lsum + rsum + node.val if lbst and rbst and lmax < node.val < rmin: ans[0] = max(ans[0], sums) if lmin == MAX: lmin = node.val if rmax == MIN: rmax = node.val return [True, lmin, rmax, sums] else: return [False, lmin, rmax, sums] dfs(root) return ans[0] if __name__ == "__main__": root = constructBinaryTree([1,4,3,2,4,2,5,null,null,null,null,null,null,4,6]) root.prettyPrint() print(Solution().maxSumBST(root)) root = constructBinaryTree([4,3,null,1,2]) root.prettyPrint() print(Solution().maxSumBST(root)) root = constructBinaryTree([-4,-2,-5]) root.prettyPrint() print(Solution().maxSumBST(root)) root = constructBinaryTree([8,9,8,null,9,null,1, null, null, null, null, null,null,-3,5,null, null, null, null, null, null, null, null, null, null, null, null, null,-2,null,6]) root.prettyPrint() print(Solution().maxSumBST(root))
if ld: return True, True, lpath if rd: return True, True, rpath return True, False, dir if node.val == destValue: if ls: return True, True, 'U' * len(lpath) if rs: return True, True, 'U' * len(rpath) return False, True, dir if ls and ld: return ls, ld, lpath if rs and rd: return rs, rd, rpath if ls and rd: return ls, rd, 'U' * len(lpath) + rpath if rs and ld: return rs, ld, 'U' * len(rpath) + lpath if ls or ld: return ls, ld, dir + lpath if rs or rd: return rs, rd, dir + rpath return False, False, dir _, _, path = dfs(root, '') return path if __name__ == "__main__": root = constructBinaryTree([5, 1, 2, 3, null, 6, 4]) root.prettyPrint() print(Solution().getDirections(root, startValue=3, destValue=6)) print(Solution().getDirections2(root, startValue=3, destValue=6)) root = constructBinaryTree([2, 1]) print(Solution().getDirections(root, startValue=2, destValue=1)) print(Solution().getDirections2(root, startValue=2, destValue=1)) root = constructBinaryTree([1, 2]) print(Solution().getDirections(root, startValue=2, destValue=1)) print(Solution().getDirections2(root, startValue=2, destValue=1))
from typing import Optional, List from BinaryTree import null, TreeNode, constructBinaryTree class Solution: def printTree(self, root: Optional[TreeNode]) -> List[List[str]]: def height(node): if not node: return 0 return 1 + max(height(node.left), height(node.right)) def update(node, row, left, right): if not node: return mid = left + (right - left) // 2 res[row][mid] = str(node.val) update(node.left, row + 1, left, mid - 1) update(node.right, row + 1, mid + 1, right) h = height(root) - 1 w = 2**(h + 1) - 1 res = [[''] * w for _ in range(h + 1)] update(root, 0, 0, w - 1) return res if __name__ == "__main__": root = constructBinaryTree([1, 2, 3, null, 4]) root.prettyPrint() for row in Solution().printTree(root): print(row)
5 7 1 Note: The size of the BST will not exceed 50. The BST is always valid and each node’s value is different. ''' from BinaryTree import (null, TreeNode, constructBinaryTree) class Solution(object): def splitBST(self, root, V): res = [None, None] if not root: return res if root.val <= V: res = self.splitBST(root.right, V) root.right = res[0] res[0] = root else: res = self.splitBST(root.left, V) root.left = res[0] res[1] = root return res if __name__ == "__main__": root = constructBinaryTree([4,2,6,1,3,5,7]) root.prettyPrint() res = Solution().splitBST(root, 2)
# self.val = val # self.left = left # self.right = right from BinaryTree import (TreeNode, constructBinaryTree, null) class Solution(object): def bstToGst(self, root): """ :type root: TreeNode :rtype: TreeNode """ def dfs(root, rsum): if root is None: return dfs(root.right, rsum) rsum[0] += root.val root.val = rsum[0] dfs(root.left, rsum) return dfs(root, [0]) return root if __name__ == "__main__": root = constructBinaryTree( [4, 1, 6, 0, 2, 5, 7, null, null, null, 3, null, null, null, 8]) print(root.val) Solution().bstToGst(root) print(root.left.right.right.val)
class Solution(object): def zigzagLevelOrder(self, root): """ :type root: TreeNode :rtype: List[List[int]] """ if not root: return [] q = deque([root]) res = [] lev = 1 while q: nxt = deque() nums = [] while q: node = q.popleft() if node.left: nxt.append(node.left) if node.right: nxt.append(node.right) nums.append(node.val) if lev % 2 == 0: nums = nums[::-1] res.append(nums) q = nxt lev += 1 return res if __name__ == "__main__": root = constructBinaryTree([3, 9, 20, null, null, 15, 7]) root.prettyPrint() print(Solution().zigzagLevelOrder(root))
node, lvl = que.popleft() if node.left: idx = 2 * lvl if i == -1: i = idx else: j = idx nxt.append((node.left, idx)) if node.right: idx = 2 * lvl + 1 if i == -1: i = idx else: j = idx nxt.append((node.right, idx)) if i >= 0 and j >= 0: res = max(res, j - i + 1) que = nxt return res if __name__ == "__main__": root = constructBinaryTree([1, 3, 2, 5, 3, null, 9]) print(Solution().widthOfBinaryTree(root)) root = constructBinaryTree([1, 3, null, 5, 3]) root.prettyPrint() print(Solution().widthOfBinaryTree(root)) root = constructBinaryTree([1, 3, 2, 5]) root.prettyPrint() print(Solution().widthOfBinaryTree(root)) root = constructBinaryTree( [1, 3, 2, 5, null, null, 9, 6, null, null, null, null, null, null, 7]) root.prettyPrint() print(Solution().widthOfBinaryTree(root))
:rtype: int """ self.res = 0 def helper(root, m): if root.val in m: m[root.val] += 1 else: m[root.val] = 1 if not root.left and not root.right: odd = 0 for k in m.values(): if k % 2 != 0: odd += 1 if odd <= 1: self.res += 1 m[root.val] -= 1 if m[root.val] == 0: m.pop(root.val) return if root.left: helper(root.left, m) if root.right: helper(root.right, m) # dict is mutable, so when backtracking, need to # erase the current node's value m[root.val] -= 1 if m[root.val] == 0: m.pop(root.val) return helper(root, {}) return self.res if __name__ == "__main__": root = constructBinaryTree([2, 3, 1, 3, 1, null, 1]) root.prettyPrint() print(Solution().pseudoPalindromicPaths(root))
def countUnivalSubtrees(self, root): bb = [True] def isUnival(root, b): if not root: return 0 l, r = [True], [True] left = isUnival(root.left, l) right = isUnival(root.right, r) res = left + right b[0] = l[0] and r[0] and ( root.val == root.left.val if root.left else True) and (root.val == root.right.val if root.right else True) return res + b[0] return isUnival(root, bb) if __name__ == "__main__": #''' root = constructBinaryTree([5, 1, 5, 5, 5, null, 5]) print(Solution().countUnivalSubtreesAC(root)) root = constructBinaryTree([1, 3, 2, 4, 5, null, 6]) print(Solution().countUnivalSubtreesAC(root)) #''' #root = constructBinaryTree([1,1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1]) root = constructBinaryTree([1, 1, 1, 1, 1, -1]) root.prettyPrint() print(Solution().countUnivalSubtrees(root)) print(Solution().countUnivalSubtreesAC(root))
from BinaryTree import (null, TreeNode, constructBinaryTree) class Solution: """ @param root: the root @return: the largest subtree's size which is a Binary Search Tree """ def largestBSTSubtree(self, root): # Write your code here MIN, MAX = -float('inf'), float('inf') res = [0] def helper(node): if not node: return (MAX, MIN, 0, True) lmin, lmax, lnum, lis = helper(node.left) rmin, rmax, rnum, ris = helper(node.right) if lmax <= node.val <= rmin and lis and ris: res[0] = max(res[0], lnum+rnum+1) return (min(node.val, lmin, rmin), max(node.val, lmax, rmax), lnum+rnum+1, True) else: return (min(node.val, lmin, rmin), max(node.val, lmax, rmax), lnum+rnum+1, False) helper(root) return res[0] if __name__ == "__main__": root = constructBinaryTree([10,5,15,1,8,null,7]) root.prettyPrint() print(Solution().largestBSTSubtree(root))
y = root if x is None: x = pre pre = root pnt.right = None root = root.right else: if pre and pre.val > root.val: y = root if x is None: x = pre pre = root root = root.right #print('x,y: ',x.val, y.val) x.val, y.val = y.val, x.val if __name__ == '__main__': root = constructBinaryTree([3,1,4,null,null,2,null]) print(root.val) Solution().recoverTree(root) print(root.val) root = constructBinaryTree([5,2,6,1,8,null,3]) inOrder(root) Solution().recoverTree(root) inOrder(root) #print(root.left.right.right.val)
else: #pre = root if root.val == 6: print(pre.val, pre.right.val) # 2) the second visit of its predecessor 'pre' # break the thread towards pre to restore the original # tree structure # NOTE: the condition that leads to here is # root.val == pre.right.val pre.right = None #print(' ', root.val,'->',end='') root = root.right else: #pre = root if root.val == 6: print(root.right.val) #print(' ',root.val,'->', end='') root = root.right #print('x,y: ',x.val, y.val) print('') #x.val, y.val = y.val, x.val if __name__ == '__main__': root = constructBinaryTree( [6, 2, 7, 1, 4, null, 9, null, null, 3, 5, null, null, 8, null]) #inOrder(root) Solution().recoverTree(root) #inOrder(root) #print(root.left.right.right.val)
from BinaryTree import (null, TreeNode, constructBinaryTree) class Solution(object): def trimBST(self, root, low, high): """ :type root: TreeNode :type low: int :type high: int :rtype: TreeNode """ def helper(root): if not root: return None if low <= root.val <= high: root.left = helper(root.left) root.right = helper(root.right) return root elif root.val < low: return helper(root.right) elif root.val > high: return helper(root.left) return helper(root) if __name__ == "__main__": root = constructBinaryTree([3, 0, 4, null, 2, null, null, null, null, 1]) root.prettyPrint() newroot = Solution().trimBST(root, 1, 3) newroot.prettyPrint()