2-sum问题

问题描述

输入一个整数数组和一个整数,在数组中查找一对数,满足他们的和正好是输入的那个整数。

分析求解

暴力求解法

——从数组中任意选两个数,判定他们的和是否等于输入的那个数。时间复杂度O(n^2)。

双层循环,检查所有元素对:

public static int count(int[] a, int sum)
{
    N = a.length();
    int cnt = 0;

    for(int I = 0; I < N; I++)
        for(int j = I + 1; j < N; j++)
        {
            if(a[i] + a[j] == sum)
                cnt++;
        }   
    return cnt;
}

散列映射

利用“以空间换时间”的思想,花费O(n)的空间构造一个散列表,然后根据给定的数,用散列映射查找另一个数是否也在数组中,花费O(1)的时间,查询n次,总的时间复杂度是O(n)。

利用归并排序和二分查找

  • 如果二分查找不成功则会返回-1,因此我们不会增加计数器的值;
  • 如果二分查找返回的 j > i, 我们就有a[i] + a[j] = sum,增加计数器的值;
  • 如果二分查找返回的 j 在 0 和 i 之间,我们也有a[i] + a[j] = sum,但不能增加计数器的值,避免重复计数。
public static int count(int[] a, int sum)
{
    Arrays.sort(a);
    int N = a.length();
    int cnt = 0;
    for(int I = 0; I < N; I++)
    {
        if(BinarySearch.rank(sum - a[i], a) > i)
            cnt++;
    }
    return cnt;
}

归并排序所需的时间和NlogN成正比;二分查找的时间和logN成正比,乘外循环N后时间和NlogN成正比;因此算法的时间复杂度为NlogN。
注:3- sum用此法时间复杂度为O{(N^2)*logN}.

双指针法

可以用两个指针 begin 和 end 分别指向数组的首尾两端, 令 begin=0, end = N-1, 然后begin++, end–, 逐次判断 a[begin] + a[end] 是否等于给定的值sum。

  • 如果某一刻 a[begin] + a[end] > sum, 则要想办法让a[begin] + a[end]的值减小,所以此刻 begin 不动,end–;
  • 如果某一刻 a[begin] + a[end] < sum, 则要想办法让 a[begin] + a[end]的值增大,所以此刻 begin++, end不动。
pubic static int count(int a[], sum)
{
    Arrays.sort(a);
    int N = a.length();
    int cnt = 0;

    int begin = 0;
    int end = N - 1;

    while(begin < end)
    {
        int corrSum = a[begin] + a[end];
        if(currSum == sum)
        {
            cnt++;
            System.out.printf("%d %d\n", a[begin], a[end]);

            begin++;
            end--;
            break;
        }
        else
        {
            if(currSum < sum)
                begin++;
            else
                end--;
        }
    }
    return cnt;
}

如果在数组有序的前提下,直接用两个指针分别从头和尾向中间扫描的方法,时间复杂度为O(n), 且空间复杂度为 O(1)。 ——很明显,在数组有序的情况下,这种方法是目前能想到的 最优 的。
排完序后用连个指针分别从头和尾向中间扫描的方法,总的时间复杂度为O(NlogN + N) = O(NlogN), 空间复杂度为O(1)。

    原文作者: 汉诺塔问题
    原文地址: https://blog.csdn.net/Shingle_/article/details/51762675
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞