1. 程式人生 > >Leetcode 230. 二叉搜尋樹中第K小的元素 C++

Leetcode 230. 二叉搜尋樹中第K小的元素 C++

題目描述

在這裡插入圖片描述

方法一(中序歷遍思想)

使用樹的中序歷遍,對於二叉搜尋樹,樹的中序歷遍得到的就是按照從小到大排序的一個序列。這裡做了適當的改進,歷遍的時候不再將數值儲存到一個數組中,這樣就不需要佔用記憶體。直接通過記錄當前歷遍到第 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個節點。那麼在右子樹中,只需要找第 l

e f t _ n o d e 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