Binary Search Tree - LeetCode 解析

186 阅读10分钟

Q96: Unique Binary Search Trees

Givenn, how many structurally unique BST's (binary search trees) that store values 1 ...n?

Example:

Input: 3
Output: 5
Explanation:
Given n = 3, there are a total of 5 unique BST's:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

Constraints:

  • 1 <= n <= 19

BST的规律性是很强的:若F(n)表示[1...n]能够构成的不同BST的数量,那么:

1、特殊情况,如果结点数为0,即n=0,为空树,F(0)=1;

2、如果结点数为1,即n=1,F(1)=1;

3、如果结点数为2,即n=2,F(2)=2;

4、对于n>=2的情况,事实上,1,2,..n都可以作为根节点,若i作为根节点,根据BST的性质,左子树不为空时(左子树为空,只能是i=1),左子树的所有节点必须小于根节点,即**[1,i-1]必须位于左子树**,同时,右子数节点必须值必须大于根节点值,则**[i+1,n]必须位于右子树;**

5、如上分析,对于[1,n],n>=2的情况,既然[1,n]每一个值都可以作为根节点,那我们需要遍历所有情况,时间复杂度为O(n),对于任何一种情况:根节点为i,则[1,i-1]为左子树,[i+1,n]为右子树,左子树有能够构成不同的BST的数量为:F(i-1),右子树能够构成的不同BST的数量为F(n-i);

左右植树相互独立,那么:F(n)=F(i-1)*F(n-i),i属于[1,n],i有n种情况,须完全遍历

6、进一步地,我们将这个问题数学化:

7、根据上面的公式,写出代码很容易,两重循环,时间复杂度O(n2)

解法及注释

Q95: Unique Binary Search Trees II

Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ...n

Example:

Input: 3
Output:
[
  [1,null,3,2],
  [3,2,null,1],
  [3,1,null,null,2],
  [2,1,3],
  [1,null,2,null,3]
]
Explanation:
The above output corresponds to the 5 unique BST's shown below:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

这道题是之前的延伸,之前那个只要求算出所有不同的二叉搜索树的个数,这道题让把那些二叉树都建立出来。这种建树问题一般来说都是用递归来解,这道题也不例外,划分左右子树,递归构造。这个其实是用到了大名鼎鼎的分治法 Divide and Conquer,类似的题目还有之前的那道 Different Ways to Add Parentheses 用的方法一样,用递归来解,划分左右两个子数组,递归构造。刚开始时,将区间 [1, n] 当作一个整体,然后需要将其中的每个数字都当作根结点,其划分开了左右两个子区间,然后分别调用递归函数,会得到两个结点数组,接下来要做的就是从这两个数组中每次各取一个结点,当作当前根结点的左右子结点,然后将根结点加入结果 res 数组中即可.

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<TreeNode> generateTrees(int n) {
        //pre-check
        if(n <= 0)
            return Collections.emptyList();
        
        return support(1, n);
    }
    
    private List<TreeNode> support(int start, int end) {
        List<TreeNode> res = new ArrayList();
        if(start > end) {
            res.add(null);
            return res;
        }
        
        for(int i = start; i <= end; i++) {
            List<TreeNode> left = support(start, i - 1);
            List<TreeNode> right = support(i + 1, end);
            for(TreeNode nl : left) {
                for(TreeNode nr : right) {
                    res.add(new TreeNode(i, nl, nr));
                }
            }
        }
        return res;    
    }
}

Q98. Validate Binary Search Tree

Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than the node's key.
  • Both the left and right subtrees must also be binary search trees.

Example 1:

    2
   / \
  1   3

Input: [2,1,3]
Output: true

Example 2:

    5
   / \
  1   4
     / \
    3   6

Input: [5,1,4,null,null,3,6]
Output: false
Explanation: The root node's value is 5 but its right child's value is 4.

The idea above could be implemented as a recursion. One compares the node value with its upper and lower limits if they are available. Then one repeats the same step recursively for left and right subtrees.

Complexity Analysis

  • Time complexity :
    O(N) since we visit each node exactly once.
  • Space complexity :
    O(N) since we keep up to the entire tree.

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isValidBST(TreeNode root) {
        return support(root, null, null);        
    }
    
    private boolean support(TreeNode node, Integer lower, Integer upper) {
        //pre-check
        if(node == null) return true;
        
        int val = node.val;
        if(lower != null && val <= lower) return false;
        if(upper != null && val >= upper) return false;
        
        if(!support(node.right, val, upper)) return false;
        if(!support(node.left, lower, val)) return false;
        
        return true;
        
    }
}

Q102 Binary Tree Level Order Traversal

Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).

For example:
Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

return its level order traversal as:

[
  [3],
  [9,20],
  [15,7]
]

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList();
        
        if(root == null) return res;
        
        traverse(root, res);
        
        return res;        
    }
    
    void traverse(TreeNode node, List<List<Integer>> res) {
        Queue<TreeNode> queue = new LinkedList();
        queue.add(node);
        
        while(!queue.isEmpty()) {
            int size = queue.size();
            List<Integer> currentLvl = new ArrayList();
            
            for(int i = 0; i < size; i++) {
                TreeNode curr = queue.poll();
                currentLvl.add(curr.val);
                if(curr.left != null)  queue.add(curr.left);
                if(curr.right != null) queue.add(curr.right);
            }
            res.add(currentLvl);
        }
    }
}

Q103 Binary Tree Zigzag Level Order Traversal

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).

For example:
Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

return its zigzag level order traversal as:

[
  [3],
  [20,9],
  [15,7]
]

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList();
        if(root == null) return res;
        
        traverse(root, res);
        return res;
        
    }
    
    void traverse(TreeNode root, List<List<Integer>> res) {
        Stack<TreeNode> currentLevel = new Stack();
        Stack<TreeNode> nextLevel = new Stack();
        currentLevel.push(root);
        boolean leftToRight = true;
        
        while(!currentLevel.empty()) {
            int size = currentLevel.size();
            List<Integer> currentRes = new ArrayList();

            for(int i = 0; i < size; i++) {
                TreeNode curr = currentLevel.pop();
                currentRes.add(curr.val);
                if(leftToRight) {
                   if(curr.left != null) nextLevel.push(curr.left); 
                   if(curr.right != null) nextLevel.push(curr.right);
                } else {
                   if(curr.right != null) nextLevel.push(curr.right); 
                   if(curr.left != null) nextLevel.push(curr.left); 
                }

            }
                
            res.add(currentRes);
            currentLevel = new Stack();
            while(!nextLevel.empty()) {
                Stack<TreeNode> temp = currentLevel;
                currentLevel = nextLevel;
                leftToRight = !leftToRight;
            }
            nextLevel = new Stack();
        }
    }
}

Q104 Maximum Depth of Binary Tree

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

Note: A leaf is a node with no children.

Example:

Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

return its depth = 3.

**解法及注释
**

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        //pre-check
        if(root == null) 
            return 0;
        return getDepth(root) + 1;
        
    }
    
    int getDepth(TreeNode node) {
        if(node == null)
            return -1;
        
        int left = 1 + getDepth(node.left);
        int right = 1 + getDepth(node.right);
        return Math.max(left, right);
    }
}

Q105 Construct Binary Tree from Preorder and Inorder Traversal

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

For example, given

preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]

Return the following binary tree:

    3
   / \
  9  20
    /  \
   15   7

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int[] pre, in;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        pre = preorder;
        in = inorder;
        
        return support(0, pre.length, 0, in.length);
    }
    
    private TreeNode support(int pStart, int pEnd, int iStart, int iEnd) {
        if(pEnd < pStart || iEnd < iStart || pStart >= pre.length || iStart >= in.length) return null;
        
        TreeNode node = new TreeNode(pre[pStart]);
        int l = -1;  // find out the length of left and right subtree
        for(int i = iStart; i <= iEnd; i++) {
            if(in[i] == pre[pStart]) {
                l = i - iStart;
                break;
            }
        }
        
        node.left = support(pStart + 1, pStart + l, iStart, iStart + l -1);
        node.right = support(pStart +l + 1, pEnd, iStart + l + 1, iEnd);
        return node;
    }
}

Q106 Construct Binary Tree from Inorder and Postorder Traversal

Given inorder and postorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

For example, given

inorder = [9,3,15,20,7]
postorder = [9,15,7,20,3]

Return the following binary tree:

    3
   / \
  9  20
    /  \
   15   7

解法及注释

除了递归的解法,这个题目其实有一个条件, 前面没有仔细说, 就是二叉树的每个节点的值都是不一样的这个条件其实非常重要,原因是,我们从postorder的最后一个可以得到root的值但是在inorder中遍历的时候,就是根据这个值来找inorder的, 

否则如果有重复的值的话,那是不知道那个值是根节点的所以这里每次找这个根节点的值,不需要循环去遍历, 可以提前建立value->index的map,
然后每次直接在map里面找就好了

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        Map<Integer, Integer> indexMap = new HashMap<>();
        for(int i = 0; i < inorder.length; ++i) {
            indexMap.put(inorder[i], i);
        }
        return build(indexMap, inorder, 0, inorder.length-1, postorder, 0, postorder.length-1);
    }
    
    public TreeNode build(Map<Integer, Integer> indexMap, int[] inorder, int inStart, int inEnd, 
                          int[] postorder, int postStart, int postEnd) {
        if(inStart > inEnd) return null;
        TreeNode root = new TreeNode(postorder[postEnd]);
        int i = indexMap.get(postorder[postEnd]);
        int len = i - inStart;
        
        root.left = build(indexMap, inorder, inStart, i-1, postorder, postStart, postStart + len-1);                
        root.right = build(indexMap, inorder, i+1, inEnd, postorder, postStart+len, postEnd-1);
        
        return root;
    }
}

Q107 Binary Tree Level Order Traversal II

Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).

For example:
Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

return its bottom-up level order traversal as:

[
  [15,7],
  [9,20],
  [3]
]

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        //pre-check
        if(root == null)
            return Collections.emptyList();
        
        List<List<Integer>> res = new ArrayList();
        Stack<List<Integer>> stack = new Stack();
        Queue<TreeNode> queue = new LinkedList();   
        queue.offer(root);
        
        while(!queue.isEmpty()){
            int size = queue.size();
            List<Integer> currLvl = new ArrayList();
            
            for(int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                currLvl.add(node.val);
                if(node.left != null)  queue.offer(node.left);
                if(node.right != null) queue.offer(node.right);
            }
            
            stack.push(currLvl);
        }
        
        while(!stack.empty())
            res.add(stack.pop());   
        
        return res;
    }
}

Q108 Convert Sorted Array to Binary Search Tree

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of

every

node never differ by more than 1.

Example:

Given the sorted array: [-10,-3,0,5,9],

One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:

      0
     / \
   -3   9
   /   /
 -10  5

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        //pre-check
        if(nums == null || nums.length == 0)
            return null;
        
        return sortArray(nums, 0, nums.length - 1);
        
    }
    
    private TreeNode sortArray(int[] nums, int start, int end) {
        if(start > end) 
            return null;
        if(start == end) {
            TreeNode node = new TreeNode(nums[start]);
            return node;
        }
        
        int mid = start + (end - start) / 2;
        TreeNode node = new TreeNode(nums[mid]);
        node.left = sortArray(nums, start, mid - 1);
        node.right = sortArray(nums, mid + 1, end);
        return node;
    }
}

Q112 Path Sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

Note: A leaf is a node with no children.

Example:

Given the below binary tree and sum = 22,

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \      \
7    2      1

return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
        //pre-check
        if(root == null)
            return false;
        
        if(root.left == null && root.right == null)
            return sum == root.val;
        
        return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
    }
}

Q113 Path Sum II

Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.

Note: A leaf is a node with no children.

Example:

Given the below binary tree and sum = 22,

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \    / \
7    2  5   1

Return:

[
   [5,4,11,2],
   [5,8,4,5]
]

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int sum) {
        List<List<Integer>> res = new ArrayList();
        if(root == null) return res;
        
        List<Integer> currRes = new ArrayList<Integer>();
        
        if(root.val == sum && root.left == null && root.right == null) {
            currRes.add(root.val);
            res.add(currRes);
            return res;
        } else {
            List<List<Integer>> tmpRes = pathSum(root.left, sum - root.val);
            tmpRes.addAll(pathSum(root.right, sum - root.val));
            
            for(List<Integer> l : tmpRes)
                l.add(0, root.val);
            
            if(tmpRes.size() > 0)
                res.addAll(tmpRes);
        }
        return res;
    }
}

Q437 Path Sum III

You are given a binary tree in which each node contains an integer value.

Find the number of paths that sum to a given value.

The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).

The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.

Example:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

      10
     /  \
    5   -3
   / \    \
  3   2   11
 / \   \
3  -2   1

Return 3. The paths that sum to 8 are:

1.  5 -> 3
2.  5 -> 2 -> 1
3. -3 -> 11

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    
    private List<Integer> path;
    
    private int pathCount;
    
    public Solution() {
        this.path = new ArrayList<>();    
        this.pathCount = 0;
    }
    
    public int pathSum(TreeNode root, int sum) {
        findSum(root, sum);
        return this.pathCount;
    }
    
    /* Idea is to traverse the tree, adding nodes to the list and then checking if we've reached the required sum starting from the last visited node */
    private void findSum(TreeNode root, int sum) {
        if(root == null) return;
        this.path.add(root.val);
        findSum(root.left, sum);
        findSum(root.right, sum);
        int tempSum = 0;
        /* Now check if the required sum is achieved starting the from the last visited node */
        for(int index=this.path.size()-1;index>=0;index--) {
            tempSum += this.path.get(index);
            if(tempSum == sum) this.pathCount++;
        }
        
        /* Remove this node from the list to avoid considering this nodes value again */
        this.path.remove(this.path.size()-1);
    }
}

Q671 Second Minimum Node In a Binary Tree

Given a non-empty special binary tree consisting of nodes with the non-negative value, where each node in this tree has exactly two or zero sub-node. If the node has two sub-nodes, then this node's value is the smaller value among its two sub-nodes. More formally, the property root.val = min(root.left.val, root.right.val) always holds.

Given such a binary tree, you need to output the second minimum value in the set made of all the nodes' value in the whole tree.

If no such second minimum value exists, output -1 instead.

Example 1:

Input: 
    2
   / \
  2   5
     / \
    5   7

Output: 5
Explanation: The smallest value is 2, the second smallest value is 5.

Example 2:

Input: 
    2
   / \
  2   2

Output: -1
Explanation: The smallest value is 2, but there isn't any second smallest value.

解法及注释

class Solution {
    int min1;
    long ans = Long.MAX_VALUE;

    public void dfs(TreeNode root) {
        if (root != null) {
            if (min1 < root.val && root.val < ans) {
                ans = root.val;
            } else if (min1 == root.val) {
                dfs(root.left);
                dfs(root.right);
            }
        }
    }
    public int findSecondMinimumValue(TreeNode root) {
        min1 = root.val;
        dfs(root);
        return ans < Long.MAX_VALUE ? (int) ans : -1;
    }
}

Q173 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.

Example:

BSTIterator iterator = new BSTIterator(root);
iterator.next();    // return 3
iterator.next();    // return 7
iterator.hasNext(); // return true
iterator.next();    // return 9
iterator.hasNext(); // return true
iterator.next();    // return 15
iterator.hasNext(); // return true
iterator.next();    // return 20
iterator.hasNext(); // return false

Note:

  • next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.

  • You may assume that next() call will always be valid, that is, there will be at least a next smallest number in the BST when next() is called.

解法及注释

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class BSTIterator {
    
    Stack<TreeNode> stack;

    public BSTIterator(TreeNode root) {
        stack = new Stack<TreeNode>();
        leftMostInOrder(root);
    }
    
    /** @return the next smallest number */
    public int next() {
        TreeNode node = stack.pop();
        if(node.right != null)
            leftMostInOrder(node.right);
        
        return node.val;
    }
    
    /** @return whether we have a next smallest number */
    public boolean hasNext() {
        return stack.size() > 0;
    }
    
    private void leftMostInOrder(TreeNode root) {
        while(root != null) {
            stack.push(root);
            root = root.left;
        }
    }
}

/**
 * Your BSTIterator object will be instantiated and called as such:
 * BSTIterator obj = new BSTIterator(root);
 * int param_1 = obj.next();
 * boolean param_2 = obj.hasNext();
 */