题目描述
出处 https://leetcode.com/problems/count-of-smaller-numbers-after-self/description/
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).
分析
- 方法一:这道题我的最初想法是暴力求解,即直接使用n次循环,每次循环遍历所给数组,计算出数组从第i个数开始后面有多少个数比第i个数小。但这种方法的计算复杂度比较高达到了O( n 2 n^2 n2),显然这是比较复杂的。
- 方法二:因为题目要求是计算出数组从第i个数开始后面有多少个数比第i个数小,所以想到了对所给的数组进行排序,为实现题目的要求,即可从前向后遍历排序后的数组,每次寻找到原数组第i个数,并在寻找后从排序的数组中删除,即可达到题目的要求。
代码注意事项
- 由于题目所给的数组是使用vector传入,因此在获取数组长度时使用了size()函数,这里会有个隐藏问题,当vec的size为0时,因为size()函数的返回值是无符号整型,这时vec.size()-1是一个正数,导致vec[i]的访问越界,因此修改为后面的一种写法。
vector<int> vec;
for (int i = 0; i < vec.size() - 1; i++){
vec[i]
}
vector<int> vec;
int n = vec.size();
for (int i = 0; i < n - 1; i++){
vec[i]
}
- vector可以直接使用sort函数进行排序。(对a中的从a.begin()(包括它)到a.end()(不包括它)的元素进行从小到大排列)
#include<algorithm>
sort(a.begin(),a.end());
- 但在查找vector中数字对应位置时,不可以使用find函数, find函数只能用于判断在数组中是否存在查找元素,不能从数组中找到所查元素的位置。(在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置)
#include<algorithm>
vector<int>::iterator result = find(a.begin( ), a.end( ), 10);
if (result == a.end())
cout << "No" << endl;
else
cout << "Yes" << endl;
- 因此为了实现查找,自己写了一个简单的二分查找方法,在实现查找时还应注意原数组中可能出现重复的情况,因次需要对二分查找进行一定的修改。
最终结果
class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
vector<int> tem(nums);
int n = nums.size();
vector<int> count(n, 0);
sort(tem.begin(), tem.end());
for (int i = 0; i < n-1; i++) {
int num = find(nums[i], tem);
count[i] = num;
tem.erase(tem.begin()+num);
}
return count;
}
int find(int num, vector<int>& tem) {
int mid = 0, start = 0, end = tem.size();
end -= 1;
while (1) {
mid = (start + end) / 2;
if (tem[mid] == num) {
break;
} else if (tem[mid] > num) {
end = mid-1;
} else {
start = mid+1;
}
}
while (mid != 0 && tem[mid] == tem[mid-1])
mid --;
return mid;
}
};