《编程之美》——快速寻找符合条件的两个数

问题:
快速找出一个数组中的两个数字,使两个数字之和为一个特定的值。假设数组中至少存在一组符合要求的解。

分析与解法:
【解法一】
穷举,从数组中任意选取两个数字,计算两个数字之和是否等于给定的数字。时间复杂度为O(n^2)

【解法二】
对数组中的每个数arr[i]都判定sum-arr[i]是否在数组中,于是题目就变成了一个查找算法。可以先对数组进行排序,再使用二分法进行查找,总的时间复杂度为O(2*nlogn)

【解法三】
使用空间换时间的方法,使用hash表。对每个数arr[i]在表中查找sum-arr[i],每次查找时间复杂度为O(1),总的时间复杂度为O(n)

代码:

void find(int[] arr, int sum, int n){
        int[] index = new int[2];
        index[0] = -1;
        index[1] = -1;
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < n; i++){
            if(map.containsKey(sum - arr[i]) == false){
                map.put(arr[i], i);
            }
            else{
                index[0] = map.get(sum - arr[i]);
                index[1] = i;
                System.out.println(index[0] + " " + index[1]);
            }
        }
        System.out.println(index[0] + " " + index[1]);
    }

【解法四】
先对数组进行排序,时间复杂度为O(nlogn),再使用双游标的方法分别从有序数组的前后对数组之和进行扫描,时间复杂度为O(n),总的时间复杂度为O(nlogn)

代码:

/*在有序数组中查找和为sum的两个数*/
void find(int arr[], int sum, int n)
{
    int i, j;
    i = 0;
    j = n - 1;
    while(i < j)
    {
        if(arr[i] + arr[j] < sum)
            i++;
        else if(arr[i] + arr[j] > sum)
            j--;
        else
            cout << i << "," << j;
    }
}

扩展问题:
1.如果问题中“两个数字”改为“三个数字”或“任意个数字”该如何求解?

分析与解法:
1.属于动态规划的背包问题。需要考虑不放两种情况。
代码:
http://blog.csdn.net/wuzhekai1985/article/details/6728657

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值