表示这道题我一开始没有什么思路,在网上发现一个二叉搜索树的方法,感觉很奇妙,分享给大家,原网址见文末,具体思路其实很简单,因为用了二叉搜索树的特性,又快又好,赞!
若对二叉搜索树c++实现有兴趣可以进入我的github上的BST。
struct BSTNode {
int val;
int count; // int count: 这个val代表的次数也就是在nums数组种比val小的数的个数
BSTNode *left;
BSTNode *right;
BSTNode(int x) : val(x), left(NULL), right(NULL), count(0){}
};
// count_small作为一个引用的参数, 在递归寻找子树的时候作为一个"类似全局变量"的存在
void BST_insert(BSTNode *node, BSTNode *insert_node, int &count_small) {
if (node->val >= insert_node->val) {
// 插入的结点更小, 被比较结点(即node)的count++, 然后插入到左子树(如果不为空)
node->count++;
if (node->left) BST_insert(node->left, insert_node, count_small);
else node->left = insert_node; // 左子树为空,插入结点就作为当前结点的左孩子
}
else {
count_small += node->count + 1;
if (node->right) BST_insert(node->right, insert_node, count_small);
else node->right = insert_node;
}
}
class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
int n = nums.size();
if(!n) return {};
vector<int> count;
count.push_back(0);
BSTNode* node = new BSTNode(nums[n - 1]);
int count_small;
for(int i = 1; i < n; ++i) {
count_small = 0;
BST_insert(node, new BSTNode(nums[n - i - 1]), count_small);
count.push_back(count_small);
}
// 最后不要忘记删除树节点
delete node;
reverse(count.begin(), count.end());
return count;
}
};