找出数组中两数之和为指定值的所有整数对

一,问题描述

给定一个整型数组(数组中的元素可重复),以及一个指定的值。打印出数组中两数之和为指定值的 所有整数对

二,算法分析

一共有两种方法来求解。方法一借助排序,方法二采用HashSet

方法一:

先将整型数组排序,排序之后定义两个指针left和right。left指向已排序数组中的第一个元素,right指向已排序数组中的最后一个元素

将 arr[left]+arr[right]与 给定的元素比较,若前者大,right--;若前者小,left++;若相等,则找到了一对整数之和为指定值的元素。

此方法采用了排序,排序的时间复杂度为O(NlogN),排序之后扫描整个数组求和比较的时间复杂度为O(N)。故总的时间复杂度为O(NlogN)。空间复杂度为O(1)

方法二:

依次遍历整型数组,对整型数组中的每一个元素,求解它的suplement(expectedSum-arr[i]).suplement就是指定的值减去该数组元素。

如果该元素的 suplement不在HashSet中,则将该元素添加到HashSet。

如果该元素的suplement在HashSet中,说明已经找到了一对整数之和为指定值的元素。

该方法使用了HashSet,故空间复杂度为O(N),由于只需要扫描一遍整型数组,故时间复杂度为O(N)

三,完整代码实现:

import java.util.Arrays;
import java.util.HashSet;

public class ExpectSumOfTwoNumber {

    public static void expectSum_bySort(int[] arr, int expectSum)
    {
        if(arr == null || arr.length == 0)
            return;
        Arrays.sort(arr);
        int left = 0, right = arr.length - 1;

        while(left < right)
        {
            if(arr[left] + arr[right] > expectSum)
                right--;
            else if(arr[left] + arr[right] < expectSum)
                left++;
            else//equal
            {
                System.out.println(arr[left] + " + " + arr[right] + " = " + expectSum);
                left++;
                right--;
            }
        }
    }

    public static void expectSum_bySet(int[] arr, int expectSum)
    {
        if(arr == null || arr.length == 0)
            return;
        HashSet<Integer> intSets = new HashSet<Integer>(arr.length);

        int suplement;
        for (int i : arr)
        {
            suplement = expectSum - i;
            if(!intSets.contains(suplement)){
                intSets.add(i);
            }else{
                System.out.println(i + " + " + suplement + " = " + expectSum);
            }
        }
    }

    //hapjin test
    public static void main(String[] args) {
        int[] arr = {2,7,4,9,3};
        int expectSum = 11;
        expectSum_bySet(arr, expectSum);
        System.out.println("************");
        expectSum_bySort(arr, expectSum);
        System.out.println("----------------");
        int[] arr2 = {3,7,9,1,2,8,5,6,10,5};
        int expectSum2 = 10;
        expectSum_bySet(arr2, expectSum2);
        System.out.println("**********");
        expectSum_bySort(arr2, expectSum2);
    }
}

原文:http://www.cnblogs.com/hapjin/p/5746659.html

时间: 2024-12-26 00:32:35

找出数组中两数之和为指定值的所有整数对的相关文章

LeetCode第十六题-找出数组中三数之和最接近目标值的答案

3Sum Closest 问题简介: 给定n个整数的数组nums和整数目标,在nums中找到三个整数,使得总和最接近目标,返回三个整数的总和,可以假设每个输入都只有一个解决方案 举例: 给定数组:nums=[-1, 2, 1, -4], 目标值:target = 1. 最接近目标值的答案是2 (-1 + 2 + 1 = 2). 解法一: 与上一道题类似,这次要求的是三数之和与目标值的差值最小值,可以定义一个变量来记录这个差值 思路就是想先定义一个最接近的值默认取前三个数的合,然后将数组排序后 小

经典算法学习——快速找出数组中两个数字,相加等于某特定值

这个算法题的描述如下:快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值.目前我假设数组中的都是各不相等的整数.这道题是我在一次面试中被问到的,由于各种原因,我没回答上来,十分尴尬.其实这道题十分简单,我们使用相对巧妙的方法来实现下.注意不使用两层循环的元素遍历.示例代码上传至:https://github.com/chenyufeng1991/SumTo100 . 算法描述如下: (0)首先对原数组进行排序,成为递增数组: (1)对排序后的数组头部i [0]和数组尾部j [n-1]

【编程题目】找出数组中两个只出现一次的数字 ★★(自己没做出来)

61.找出数组中两个只出现一次的数字(数组)题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是 O(n),空间复杂度是 O(1). 思路:瞄到了一眼提示,说是位运算. 根据异或的运算性质: a ⊕ b ⊕ a = b 把所有的数字都异或一遍得到的结果就是 那两个只出现一次的数字异或的结果. 可怎么分出那两个数字就卡住了. 看了下网上答案,要根据得到的异或值把数字分为两组,再对每一组异或就可以得到这两个数字了! 代码如下: /* 61

面试题---找出数组中两个只出现一次的数

题目描述:给一个数组,里面有两个数只出现一次,其它的数都出现两次,请找出这两个数: 样例:输入 2 4 2 7 4 9 输出 7 9 思路:假定要找出的这两个数为x.y   把所有的数异或,结果是x与y异或的值,那么肯定不为0,那么这个值的二进制至少有一位为1,也就是说x和y的二进制在这一位上必定一个为0,一个为1,那么可以根据这一位把这个数组分成两个数组,x和y在不同的数组里,接下来对每个数组直接异或出的值就是结果了: 代码如下: #include <iostream> #include &

找出数组中两个只出现一次的数字!

实现代码: 1.PHP实现: <?php     $arr=array(1,1,5,3,2,2);          //因为每个元素都需要分别和其他的元素进行比较     //所以需要双重循环     for($i=0;$i<count($arr);$i++){                  for($j=0;$j<count($arr);$j++){                      //此处目的是避免数组元素和自己进行比较             if($i != $j

python实现给定一个数和数组,求数组中两数之和为给定的数

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数.你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 代码实现: def twoSum(self, nums, target): nums_bak = nums.copy() nums.sort() i = 0 j = 0 for k in range(0,

找出数组中两个只出现一次的数字

题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 还是理解不够深刻. 这题的主要思路还是之前的数组中只出现一次的数字的那种模式,一次遍历加上异或运算.那么这个异或的值肯定是这两个只出现一次的数字的相异或的值.那么这个值的二进制表现形式中的1的结果就表示这两个数字在该bit位上不一样.那么通过此举,我们可以以这个bit位是否为1来从整个数组中把这两个只出现一次的数字分开. 通过此举,别的出现两次的数字

找出数组中两个只出现一次的数字 【微软面试100题 第六十一题】

题目要求: 一个整型数组里除了两个数字机之外,其他的数字都出现了两次. 请写程序找出这两个只出现一次的数字.要求时间复杂度O(N).空间复杂度O(1). 参考资料:剑指offer第40题. 题目分析: 已知: 1.两个相同的数字异或的结果为0,即a^a = 0. 2.两个不相同的数字异或的结果的二进制中某一位为1,则这两个数字的二进制中对应位一个为0,一个为1.如3^2 = 1,对于最低位的二进制,3的最低位二进制为1,2的最低位二进制位0,则结果1的最低位二进制肯定为1. 假设原数组中只出现一

找出数组中唯一重复的数(转)

题目: 数组a[N],1至N-1这N-1个数存放在a[N]中,其中某个数重复一次.写一个函数,找出被重复的数字. 方法一:异或法. 数组a[N]中的N个数异或结果与1至N-1异或的结果再做异或,得到的值即为所求. 设重复数为A,其余N-2个数异或结果为B. N个数异或结果为A^A^B 1至N-1异或结果为A^B 由于异或满足交换律和结合律,且X^X = 0  0^X = X; 则有 (A^B)^(A^A^B)=A^B^B=A 代码: #include <stdio.h> #include &l