Binary Search Tree Iterator
题目如下:
Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.
Calling next() will return the next smallest number in the BST.
Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.
思路一:空间复杂度为O(N)
思路:由BST的特点可得根据中序遍历得到的节点集就是有序的。因此,借用一个容器将中序遍历的结果保存即可。
实现代码如下:
public class BSTIterator {
private List<TreeNode> list = new ArrayList<TreeNode> ();
private int totalNodeNum;
private int num;
public BSTIterator(TreeNode root) {
saveNodeToList(root);
totalNodeNum = list.size();
num = 0;
}
private void saveNodeToList(TreeNode root) {
if(root==null){
return ;
}
if(root.left!=null){
saveNodeToList(root.left);
}
list.add(root);
if(root.right!=null){
saveNodeToList(root.right);
}
}
/** @return whether we have a next smallest number */
public boolean hasNext() {
return (num<totalNodeNum);
}
/** @return the next smallest number */
public int next() {
int val = list.get(num).val;
num ++;
return val;
}
}
测试结果AC了。
但是,此种方法hasNext和next的时间复杂度为O(1),但是空间复杂度为O(N),其中N为树的节点个数,不符合题意。
虽然AC 了,但我们还需要继续思考其它更好的方法。
思路二
借用Stack来进行存储树节点。空间复杂度为O(h);
实现代码如下:
public class BSTIterator {
private Stack<TreeNode> s;
public BSTIterator(TreeNode root) {
s =new Stack<TreeNode> ();
pushLeft(root);
}
private void pushLeft(TreeNode root) {
while(root!=null){
s.push(root);
root = root.left;
}
}
/** @return whether we have a next smallest number */
public boolean hasNext() {
return !s.isEmpty();
}
/** @return the next smallest number */
public int next() {
TreeNode t = s.pop();
pushLeft(t.right);
return t.val;
}
}
运行结果如下:
小结
对比两种方法的运行结果可以得到,第一种的空间复杂度为O(N),运行时间为:5ms;第二种的空间复杂度为O(h),运行时间为:7ms;反应了这样的结论:利用空间换取时间。