Leetcode 230. 二叉搜尋樹中第K小的元素 C++
阿新 • • 發佈:2018-12-03
題目描述
方法一(中序歷遍思想)
使用樹的中序歷遍,對於二叉搜尋樹,樹的中序歷遍得到的就是按照從小到大排序的一個序列。這裡做了適當的改進,歷遍的時候不再將數值儲存到一個數組中,這樣就不需要佔用記憶體。直接通過記錄當前歷遍到第 i 個值(即第 i 大的數),和要求的 K 比較,相等就將其賦給儲存結果的變數。但是這樣做,程式仍然有優化的空間。因為,這個遞迴程式在得到了正確答案之後,並沒有停下來,仍然在繼續執行,直到完成整棵樹的中序歷遍才會終止。這裡就不再使用奇技淫巧跳出遞迴。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
int num=0;
int res=0;
fun(root, k, num,res);
return res;
}
void fun(TreeNode* root, int k, int &num, int &res)
{
if(!root) return;
fun(root->left,k,num,res);
++ num;
if(num == k)
{
res = root->val;
}
fun(root->right,k,num,res);
}
};
方法二(二分法思想)
通過計算左子樹的節點個數來判斷。如果左子樹的節點個數為 k-1 ,那麼說明根節點就是我們要找的數。如果左子樹的節點數很多(>k-1),說明要找的節點在左子樹,遞迴呼叫。如果左子樹節點較少,說明要找的節點在右子樹中。左子樹加上根節點,一共有left_node+1個節點。那麼在右子樹中,只需要找第 小的數。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
int left_node = calculate(root->left);
if(left_node == k-1) return root->val;
if(left_node >k-1) return kthSmallest(root->left, k);
if(left_node <k-1) return kthSmallest(root->right,k-left_node-1);
}
int calculate(TreeNode* root)
{
if(!root) return 0;
int node_sum=0;
node_sum = 1 + calculate(root->left) + calculate(root->right);
return node_sum;
}
};
參考:https://blog.csdn.net/suibianshen2012/article/details/52051272