方法一:
中序遍歷
用一個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);
}
}