原链接 https://leetcode.cn/problems/4xy4Wx/
看到大家都在用双指针的方法,但是双指针第一步的排序的时间复杂度就是O(NlogN),其实这个题可以用桶排序方法来实现,时间复杂度是O(N)
public int purchasePlans(int[] nums, int target) {
int N = 10000;
int mod = 1000000007;
// 数据放在N个桶中
int[] bucket = new int[N+5];
for(int num : nums){
bucket[num]++;
}
int[] dp = new int[N+5];
dp[0] = bucket[0];
// 计算出小于等于N的数据有多少个
for(int i = 1; i <= N; i++){
dp[i] = dp[i-1] + bucket[i];
}
long sum = 0;
for(int num : nums){
if(target > num){
// 这里有个小问题,就是每次算有多少个数小于target-num时,如果num也小于等于target-num,要去掉自己
int tmp = target >= 2*num? dp[target-num]-1:dp[target-num];
sum = sum + tmp;
}
}
// 每个配对第二次会重复计算,所以总数需要除以2
return (int)((sum/2)%mod);
}