力扣刷题记录 2824. 统计和小于目标的下标对数目

49 阅读1分钟

题目描述

给你一个下标从 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;
    }
}