方法一:
中序遍历
用一个ArrayList记录下中序遍历经过的结点的值
这个ArrayList实例的下标 k-1 处即为第k小的结点
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int kthSmallest(TreeNode root, int k) {
ArrayList<Integer> ans = inOrder(root,new ArrayList<Integer>());
return ans.get(k-1);
}
public ArrayList<Integer> inOrder(TreeNode root, ArrayList<Integer> res){
if(root == null) return res;
inOrder(root.left,res);
res.add(root.val);
inOrder(root.right,res);
return res;
}
}
方法二:
也是中序遍历,但是不附加ArrayList存储中序路径
private int cnt = 0;
private int val;
public int kthSmallest(TreeNode root, int k) {
inOrder(root, k);
return val;
}
private void inOrder(TreeNode node, int k) {
if (node == null) return;
inOrder(node.left, k);
cnt++;
if (cnt == k) {
val = node.val;
return;
}
inOrder(node.right, k);
}
方法三:
递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
//由BST的中序遍历是有序的,第k个结点的左子树必有k-1个结点;
//由此,当当前节点的左子树的节点总数=k-1时,当前节点就是第k个结点;当当前结点的左子树的节点总数>k-1时,第k个结点在左子树中;当当前节点的左子树的结点总数<k-1时,第k个结点在右子树。
public int kthSmallest(TreeNode root, int k) {
int leftCnt = count(root.left);
if(leftCnt == k-1) return root.val;
if(leftCnt > k-1) return kthSmallest(root.left,k)
//左子节点+上层根节点总共leftCnt+1个结点,当前根节点要满足它是以自己为根的第k-(leftCnt+1)个结点;
return kthSmallest(root.right,k -leftCnt-1);
}
public int count(TreeNode root){
if(root == null) return 0;
//树的节点总数 = 1(根节点)+左子节点 +右子节点的和
return 1+ count(root.left)+count(root.right);
}
}