public static IList<IList<int>> FindPathsWithSum(TreeNode root, List<int> path, int search) { if (root == null) { return new List<IList<int>>(); } path.Add(root.Value); List<IList<int>> results = new List<IList<int>>(); for (int i = path.Count - 1; i >= 0; i--) { IList<int> currPath = path.GetRange(i, path.Count - i); int sum = currPath.Aggregate((total, next) => { return total + next; }); if (sum == search) { results.Add(currPath); } } results.AddRange(FindPathsWithSum(root.Left, new List<int>(path), search)); results.AddRange(FindPathsWithSum(root.Right, new List<int>(path), search)); return results; }
public static TreeNode FindCommonAncestor(TreeNode root, TreeNode x, TreeNode y) { bool inLeft = IsInSubtree(root.Left, x, y); bool inRight = IsInSubtree(root.Right, x, y); if (inLeft && inRight) { return root; } // We must first check if the current node is a node we're looking for or else it will get missed if (root == x || root == y) { if (IsInSubtree(root.Left, x, y) || IsInSubtree(root.Right, x, y)) { return root; } } if (inLeft && !inRight){ return FindCommonAncestor(root.Left, x, y); } if (inRight && !inLeft) { return FindCommonAncestor(root.Right, x, y); } return null; }
private static TreeNode findLeftMostNode(TreeNode n) { if (n.Left == null) { return n; } return findLeftMostNode(n.Left); }
private static TreeNode findInOrderSuccessor(TreeNode parent, TreeNode prev) { if (parent.Left == prev) { return parent; } return findInOrderSuccessor(parent.Parent, parent); }
public static bool ContainsTree(TreeNode t1, TreeNode t2) { // null tree is always a subtree if (t2 == null) { return true; } return SubTree(t1, t2); }
public static bool IsInSubtree(TreeNode root, TreeNode x, TreeNode y) { if (root == null) { return false; } if (root == x || root == y) { return true; } return IsInSubtree(root.Left, x, y) || IsInSubtree(root.Right, x, y); }
/* * Correct way to approach the problem is you have to check EVERY node under the left and right subtree to see whether they satisfy * the condition. This is obvious very expensive, so to solve this problem you recursively pass in the min and max values a node * under the subtrees may be, updating them with the value of the next node as you continue to recurse. */ public static bool isTreeBst(TreeNode root, int min, int max) { if (root == null) { return true; } if (root.Value <= min || root.Value > max) { return false; } return isTreeBst(root.Left, min, root.Value) && isTreeBst(root.Right, root.Value, max); }
public static TreeNode InOrderSuccessor(TreeNode n) { if (n.Right != null) { return findLeftMostNode(n.Right); } else if (n.Parent != null) { return findInOrderSuccessor(n.Parent, n); } else { return null; } }
private static TreeNode arrayToBstHelper(int[] arr, int begin, int end, TreeNode parent) { if (end < begin) { return null; } int mid = (end - begin) / 2 + begin; TreeNode newNode = new TreeNode(arr[mid]); newNode.Parent = parent; newNode.Left = arrayToBstHelper(arr, begin, mid - 1, newNode); newNode.Right = arrayToBstHelper(arr, mid + 1, end, newNode); return newNode; }
// https://leetcode.com/problems/same-tree/ private static bool AreEqualTrees(TreeNode x, TreeNode y) { if (x == null && y == null) { return true; } if (x == null || y == null) { return false; } if (x.Value != y.Value) { return false; } return AreEqualTrees(x.Left, y.Left) && AreEqualTrees(x.Right, y.Right); }
private static bool SubTree(TreeNode t1, TreeNode t2) { if (t1 == null) { return false; } if (t1.Value == t2.Value) { if (AreEqualTrees(t1, t2)) { return true; } } return SubTree(t1.Left, t2) || SubTree(t1.Right, t2); }
public void Test2() { TreeNode t1 = new TreeNode(1); TreeNode t2 = new TreeNode(2); TreeNode t3 = new TreeNode(3); TreeNode t4 = new TreeNode(4); TreeNode t5 = new TreeNode(5); TreeNode t6 = new TreeNode(6); TreeNode t7 = new TreeNode(7); t1.Left = t2; t2.Left = t4; t2.Right = t5; Assert.AreEqual(-1, _01.isBalanced(t1)); }
/* * Returns -1 if not balanced, otherwise >= 0 * * Calculate height recursively on the tree and its subtrees and make sure they do not differ by more than 1. */ public static int isBalanced(TreeNode root) { if (root == null) { return 0; } int left = 1 + isBalanced(root.Left); int right = 1 + isBalanced(root.Right); if (left == 0 || right == 0) { return -1; } if (!(Math.Abs(left - right) <= 1)) { return -1; } return left > right ? left : right; }
public static IList<IList<int>> treeToLevelOrder(TreeNode root) { IList<IList<int>> resultLists = new List<IList<int>>(); Queue<TreeNode> queue = new Queue<TreeNode>(); if (root == null) { return resultLists; } queue.Enqueue(root); while (queue.Count != 0) { List<int> newLevel = new List<int>(); Queue<TreeNode> newQueue = new Queue<TreeNode>(); int queueCount = queue.Count; for (int i = 0; i < queueCount; i++) { TreeNode n = queue.Dequeue(); newLevel.Add(n.Value); if (n.Left != null) { newQueue.Enqueue(n.Left); } if (n.Right != null) { newQueue.Enqueue(n.Right); } } resultLists.Add(newLevel); queue = newQueue; } return resultLists; }
public static bool IsValidBstHelper(TreeNode root, int? min, int? max) { if (root == null) { return true; } if (min != null && root.Value <= min) { return false; } if (max != null && root.Value >= max) { return false; } return IsValidBstHelper(root.Left, min, root.Value) && IsValidBstHelper(root.Right, root.Value, max); }
/* * Above is even incorrect in a strict definition of a BST: left < root < right * Such a interpretation will run into problems with [1, 1] / [1, null, 1] and int.MaxValue and int.MinValue * * To solve such a problem you need to be able to hold 1 more value than what's possible with an int. A easy way around * this then is to simply use a nullable value which is simply not initialized when you start the search. */ public static bool IsValidBst(TreeNode root) { return IsValidBstHelper(root, null, null); }