题目描述
给你一个下标从 0 开始长度为 n 的整数数组 nums 和一个整数 target ,请你返回满足 0 <= i < j < n 且 nums[i] + nums[j] < target 的下标对 (i, j) 的数目。
解法一、暴力枚举
class Solution {
public int countPairs(List<Integer> nums, int target) {
int cnt = 0;
int n = nums.size();
for (int i = 0; i < n; i++) {
for (int j = i + 1 ; j < n; j++) {
if (nums.get(i) + nums.get(j) < target){
cnt ++;
}
}
}
return cnt;
}
}
解法二、排序+双指针
在数组有序的情况下,可以通过双向指针快速查找出下标对的数目。
具体来讲就是声明两个指针位于头尾,如果nums[left] + nums[right] < target并且数组有序(加最大值都比target小,那加比最大值小的值就更能比target小了),就说明从left到right这一段区间内所有的nums[left] + nums[left+1 ~ right] < target,那么下标对的数目就是right - left,然后继续left++找下一组。
如果nums[left] + nums[right] >= target并且数组有序(数会越来越大),那就说明从left到right这一段区间内所有的nums[left] + nums[left~right-1] >= target所以这一段区间不用考虑,让right--,让数字小一点,以便于找小于目标的下标对数目。
class Solution {
public int countPairs(List<Integer> nums, int target) {
Collections.sort(nums);
int cnt = 0;
int n = nums.size();
int left = 0,right = n - 1;
while(left < right){
if(nums.get(left) + nums.get(right) < target){
cnt += right - left;
left++;
}
else{
right --;
}
}
return cnt;
}
}