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

猜你喜欢

转载自blog.csdn.net/yuanliang861/article/details/84640069