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].
Solution1: tranverse the nums array starting from the last number, insert the number into the already ordered vector t, the index of the number in t is just counts[i]. Here use the binary search to implement the insertion.
class Solution { public: vector<int> countSmaller(vector<int>& nums) { vector<int> t, res(nums.size()); for (int i = nums.size() - 1; i >= 0; i--) { int left = 0, right = t.size(); while (left < right) { int mid = (left + right) / 2; if (t[mid] >= nums[i]) right = mid; else left = mid + 1; } res[i] = right; t.insert(t.begin() + right, nums[i]); } return res; } };
Solution 2: line 6 use the STL function lower_bound to find the positon of the insertion, however, the time complexity is O(n^2) because of the insertion.
1 class Solution { 2 public: 3 vector<int> countSmaller(vector<int>& nums) { 4 vector<int> t, res(nums.size()); 5 for (int i = nums.size() - 1; i >= 0; i--) { 6 res[i] = lower_bound(t.begin(),t.end(),nums[i])-t.begin(); 7 t.insert(t.begin() + res[i], nums[i]); 8 } 9 return res; 10 } 11 };
Solution 3:merge sort http://blog.csdn.net/qq508618087/article/details/51320926