欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Lintcode】609. Two Sum - Less than or equal to target

程序员文章站 2024-03-06 21:47:56
...

题目地址:

https://www.lintcode.com/problem/two-sum-less-than-or-equal-to-target/description

给定一个整数数组AA,再给定一个数target,求数组中有多少对数之和小于等于target。

思路是先排序,然后用对撞双指针,设左指针为ii,右指针为jj,同时比较两数之和与target的关系,并且累加结果。如果和大于target,那么就左移jj;否则,说明A[i]A[i]A[i+1],A[i+2],...,A[j]A[i+1],A[i+2],...,A[j]之和都满足条件,就将jij-i累加到结果中,同时右移ii。如此这样,直到两个指针相遇。代码如下:

import java.util.Arrays;

public class Solution {
    /**
     * @param nums: an array of integer
     * @param target: an integer
     * @return: an integer
     */
    public int twoSum5(int[] nums, int target) {
        // write your code here
        if (nums == null || nums.length < 2) {
            return 0;
        }
        
        Arrays.sort(nums);
        int res = 0;
        
        int i = 0, j = nums.length - 1;
        while (i < j) {
            int sum = nums[i] + nums[j];
            if (sum > target) {
                j--;
            } else {
                res += j - i;
                i++;
            }
        }
        
        return res;
    }
}

时间复杂度O(nlogn)O(n\log n),空间O(1)O(1)

算法正确性证明:
数学归纳法。设算法对数组长度为kk时是正确的,当数组长度为k+1k+1时,考虑计算A[i,j]A[i,j]i<ji<j)这个片段满足条件的数对个数。我们先考虑含A[i]A[i]A[j]A[j]的满足条件的数对个数。如果A[i]+A[j]>targetA[i]+A[j]>target,那么A[i,j]A[i,j]这个片段里含A[j]A[j]的所有数对都不满足条件,所以满足条件的数对个数等于A[i,j1]A[i,j-1]这个片段里满足条件的数对,根据归纳假设,算法可以算出,结论正确;如果A[i]+A[j]targetA[i]+A[j]\le target,那么A[i,j]A[i,j]这个片段里含A[i]A[i]的所有数对都满足条件,所以此时满足条件的数对个数等于jij-i加上A[i+1,j]A[i+1,j]这个片段里满足条件的数,根据归纳假设,算法可以算出,结论正确。综上,算法正确。