Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target.
Note:
- Given target value is a floating point.
- You may assume k is always valid, that is: k ≤ total nodes.
- You are guaranteed to have only one unique set of k values in the BST that are closest to the target.
Follow up:
Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)?
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * public int val; 5 * public TreeNode left; 6 * public TreeNode right; 7 * public TreeNode(int x) { val = x; } 8 * } 9 */ 10 public class Solution { 11 public IList<int> ClosestKValues(TreeNode root, double target, int k) { 12 var result = new List<int>(); 13 14 Stack<TreeNode> pred = InitPredecessorStack(root, target), succ = InitSuccessorStack(root, target); 15 16 while (result.Count < k) 17 { 18 if (pred.Count > 0 && succ.Count > 0) 19 { 20 if (pred.Peek() == succ.Peek()) 21 { 22 result.Add(GetNextSuccessor(succ)); 23 GetNextPredecessor(pred); 24 } 25 else if (Math.Abs((double)pred.Peek().val - target) <= Math.Abs((double)succ.Peek().val - target)) 26 { 27 result.Add(GetNextPredecessor(pred)); 28 } 29 else 30 { 31 result.Add(GetNextSuccessor(succ)); 32 } 33 } 34 else if (pred.Count > 0) 35 { 36 result.Add(GetNextPredecessor(pred)); 37 } 38 else 39 { 40 result.Add(GetNextSuccessor(succ)); 41 } 42 } 43 44 return result; 45 } 46 47 private Stack<TreeNode> InitSuccessorStack(TreeNode node, double target) 48 { 49 var stack = new Stack<TreeNode>(); 50 51 while (node != null) 52 { 53 if ((double)node.val == target) 54 { 55 stack.Push(node); 56 break; 57 } 58 else if ((double)node.val < target) 59 { 60 node = node.right; 61 } 62 else 63 { 64 stack.Push(node); 65 node = node.left; 66 } 67 } 68 69 return stack; 70 } 71 72 private Stack<TreeNode> InitPredecessorStack(TreeNode node, double target) 73 { 74 var stack = new Stack<TreeNode>(); 75 76 while (node != null) 77 { 78 if ((double)node.val == target) 79 { 80 stack.Push(node); 81 break; 82 } 83 else if ((double)node.val < target) 84 { 85 stack.Push(node); 86 node = node.right; 87 } 88 else 89 { 90 node = node.left; 91 } 92 } 93 94 return stack; 95 } 96 97 private int GetNextSuccessor(Stack<TreeNode> succ) 98 { 99 var top = succ.Pop(); 100 var result = top.val; 101 102 top = top.right; 103 104 while (top != null) 105 { 106 succ.Push(top); 107 top = top.left; 108 } 109 110 return result; 111 } 112 113 private int GetNextPredecessor(Stack<TreeNode> pred) 114 { 115 var top = pred.Pop(); 116 var result = top.val; 117 118 top = top.left; 119 120 while (top != null) 121 { 122 pred.Push(top); 123 top = top.right; 124 } 125 126 return result; 127 } 128 } 129 130 // time complexity O(N) 131 public class Solution1 { 132 public IList<int> ClosestKValues(TreeNode root, double target, int k) { 133 var result = new List<int>(); 134 135 DFS(root, result); 136 137 while (result.Count > k) 138 { 139 if (Math.Abs((double)result[0] - target) > Math.Abs((double)result[result.Count - 1] - target)) 140 { 141 result.RemoveAt(0); 142 } 143 else 144 { 145 result.RemoveAt(result.Count - 1); 146 } 147 } 148 149 return result; 150 } 151 152 private void DFS(TreeNode node, IList<int> result) 153 { 154 if (node == null) return; 155 156 DFS(node.left, result); 157 158 result.Add(node.val); 159 160 DFS(node.right, result); 161 } 162 }