LeetCode OJ入门初探-315. Count of Smaller Numbers After Self

You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].

Example:

Given nums = [5, 2, 6, 1]

To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.
Return the array [2, 1, 1, 0].

Subscribe to see which companies asked this question

/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/

一开始傻傻不懂,直接上暴力,果断超时。

int* countSmaller(int* nums, int numsSize, int* returnSize) {
int *returnsum = (int *)malloc(sizeof(int)*numsSize);
memset(returnsum,0,sizeof(int)*numsSize);
for(int i = 0 ; i < numsSize;i++) { int count = 0; for(int j = i;j

经过了一段思考之后打算从右往左遍历,桶排,每个nums[i]即为数组的下标,这样在计算num[i-1]时,只需找离他最近的数看其对应的值是多少,然后加一返回即可,但是,这种思路没发处理相同数字或者负数的问题。因此借鉴了网上二叉树的思路:

同样是后续遍历,但是每次获得一个value,都把他加进叔里面,小左,右大。在从root往下搜寻比其小的第一个值时,每路过一个root,root自己的统计比自己小的数量加一(注意,此时加一完全是提供给之后的搜寻使用,其smaller已经不是所要的统计值,只统计比自己小的数量,其他的在计算时由比较相加)
这样找到合适的位置,把其值加起来即可返回。动态规划的思路。

class Solution {
public:
struct Node {
int val, smaller;
Node *left, *right;
Node(int value, int small) {
left=right=NULL, val=value, smaller=small;
}
};

int insert(Node *&root, int value) {
if (root==NULL)
return (root=new Node(value, 0)), 0;

if (value < root->val)
return root->smaller++, insert(root->left, value);
else
return insert(root->right, value) + root->smaller + (value>root->val ? 1 : 0);
}

vector countSmaller(vector& nums) {
Node *root = NULL;
deque ans;
for (int i=nums.size()-1; i>=0; i--)
ans.push_front(insert(root, nums[i]));

return vector (ans.begin(), ans.end());
}
};

发表评论