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:
Input: [5,2,6,1]
Output: [2,1,1,0]
Explanation:
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.
最简单的方法,但是这道题的难度级别时hard,不可能这么简单,利用下面的代码必然超时,我胆小,没敢试。
//time complexity O(n^2)
vector<int> countSmaller(vector<int>& nums)
{
vector<int> counts(nums.size(), 0);
for (int i = 0; i < nums.size(); i++)
{
int count = 0;
for (int j = i + 1; j < nums.size(); j++)if (nums[j] < nums[i])count++;
counts[i] = count;
}
return counts;
}
时间复杂度为O(nlogn)的代码:解释都在代码里面
//time complexity O(nlogn)
int right_place_to_insert(int num, vector<int>& sorted_sequence)
{
//if the size of vector sorted_sequence is zero, it means we are dealing the last element of nums
if(sorted_sequence.size() == 0)return 0;
if(num > sorted_sequence[sorted_sequence.size() - 1])return sorted_sequence.size();
if(num <= sorted_sequence[0])return 0;
int start = 0, end = sorted_sequence.size();
while(start + 1 < end)
{
int mid = (start + end) / 2;
if(sorted_sequence[mid] >= num)end = mid;
else start = mid;
}
if(sorted_sequence[start] >= num)return start;
return end;
}
vector<int> countSmaller(vector<int>& nums)
{
//This is the vector we will put answer into
vector<int> counts(nums.size(), 0);
//What we want to know is the count of smaller number after the element with some index, just make it i.
//Then we can pass through the part between i and nums.size() - 1.
//But we need to do this any time we want to know the number smaller number after some index. And the time complexity is O(n^2)
//How can we decrease the time complexity?
//Store the number of smaller number? but we can't find the relationship among the elements of vector counts.
//And it's clear we must pass through the nums, because these elements of it are disorganized and unsorted.
//So We can decrease the time complexity by sorting the elements after some index i, and we find the position of i if we put element i into the sorted sequence.
//then we know how many elements is smaller than element i and we do put i into the sorted sequence behind, then we don't need sort them again when we want to know how many elements is smaller than the element i-1
vector<int> sorted_sequence(nums.size(), 0);
for(int i = nums.size() - 1; i >= 0; i--)
{
//the index_to_insert means the position nums[i] should stand by ascend in sorted_sequence.
int index_to_insert = right_place_to_insert(nums[i], sorted_sequence);
counts[i] = index_to_insert;
sorted_sequence.insert(sorted_sequence.begin() + index_to_insert, nums[i]);
}
return counts;
}