思路1:可以用hash表来存储数组中的元素,这样我们取得一个数后,去判断sum - val 在不在数组中,如果在数组中,则找到了一对二元组,它们的和为sum,该算法的缺点就是需要用到一个hash表,增加了空间复杂度。

思路2:同样是基于查找,我们可以先将数组排序,然后依次取一个数后,在数组中用二分查找,查找sum -val是否存在,如果存在,则找到了一对二元组,它们的和为sum,该方法与上面的方法相比,虽然不用实现一个hash表,也没不需要过多的空间,但是时间多了很多。排序需要O(nLogn),二分查找需要(Logn),查找n次,所以时间复杂度为O(nLogn)。

思路3:该方法基于第2种思路,但是进行了优化,在时间复杂度和空间复杂度是一种折中,但是算法的简单直观、易于理解。首先将数组排序,然后用两个指向数组的指针,一个从前往后扫描,一个从后往前扫描,记为first和last,如果 fist + last < sum 则将fist向前移动,如果fist + last > sum,则last向后移动。

第三种思路是最好的。

public class Main {
public static void main(String[] args) {
int[] array1 = {10,2,7,4,5,6,3,8,9,1};
int[] array2 = {1,2,3,4,5,6,7,8,9,10};
int[] array3 = {1,2,3,4,5,6,7,8,9,10};
// execute1(array1, 8);
// execute2(array2, 8);
execute3(array3, 10);
} //思路:使用hash表存储数组各元素是否存在的标志,然后遍历数组,判断sum与当前数组元素的差值是否在hash表中,
//若为真则打印,该算法不要求数组有序,但要求一个hash数组的额外空间,时间复杂度是O(n)
private static void execute1(int[] array, int m) {
int size = array.length;
int hash[] = new int[size];
for(int i = 0; i < size; i++) {
hash[array[i]%size] = 1;
} for(int i = 0; i < size; i++) {
int tmp = m - array[i];
if((tmp > array[i]) && (hash[tmp%size] == 1)){
System.out.println(array[i] + " " + tmp);
}
}
} //思路:该方法的前提是要求数组是有序的,然后再遍历数组,判断sum与数组元素的差值是否在数组中,由于数组有序所以可以采用二分查找的方法
//二分查找的时间复杂度为O(logn),排序的时间复杂度是O(nlogn),查找n次,总的时间复杂度为O(nlogn),避免了空间的浪费
private static void execute2(int[] array, int m) {
for(int i = 0; i < array.length; i++) {
int tmp = m - array[i];
if (tmp > array[i]) {
if (binarySearch(array, tmp) != -1) {
System.out.println(array[i] + " " + tmp);
}
}
}
}
private static int binarySearch(int[] array, int key) {
if (array.length == 0) {
return -1;
} int first = 0;
int last = array.length -1; int mid;
while(first <= last) {
mid = (first + last) / 2;
if (array[mid] == key) {
return mid;
} else if (array[mid] < key) {
first = mid + 1;
} else {
last = mid -1;
}
}
return -1;
} //思路:该方法的前提是要求数组是有序的,使用两个指针,分别指向最后一个元素和第一个元素,判断它们的和是否等于sum,若等于则打印,并且first向前移动,last也向前移动
//若它们的和小于sum,则说明first太小了,需要first向前移动,若它们的和大于sum,则说明last太大了,需要last向前移动,直到last>=first
private static void execute3(int[] array, int m) {
int first = 0;
int last = array.length -1;
int sum = 0;
while(first < last ) {
sum = array[first] + array[last];
if (sum == m) {
System.out.println(array[first] + " " + array[last]);
first++;
last--;
} else if (sum < m) {
first++;
} else {
last--;
}
}
}
}

http://blog.csdn.net/lalor/article/details/7554594

http://blog.csdn.net/pingnanlee/article/details/14168511

http://m.blog.csdn.net/article/details?id=50638593

Java 找到数组中两个元素相加等于指定数的所有组合的更多相关文章

  1. java实现 数组中两个元素相加等于指定数的所有组合

      package com.algorithm.hash; public class alg1 { public static void main(String argv[]) { int[] arr ...

  2. 交换数组中两个元素的位置,元素包括key和value 一维数组

    /*author: yangyu@sina.cndescription: 交换数组中两个元素的位置,元素包括key和value,具体用法见下面的例子*/$arr = array(11=>'a', ...

  3. NlogN复杂度寻找数组中两个数字和等于给定值

    算法导论:22页2.3-7 描述一个运行时间为O(nlogn)的算法,找出n个元素的S数组中是否存在两个元素相加等于给定x值 AC解: a=[1,3,6,7,9,15,29] def find2sum ...

  4. 2016网易实习生编程题:数组中两个数的和等于sum

    题目 找出数组中两个数的和等于sum的这两个数 解题 这个题目做过很多次了,利用HashMap,key为 sum-A[i] value为 i 当 加入HashMap时候A[i] 已经存在map中,ge ...

  5. leetcode-1 Two Sum 找到数组中两数字和为指定和

     问题描写叙述:在一个数组(无序)中高速找出两个数字,使得两个数字之和等于一个给定的值.如果数组中肯定存在至少一组满足要求. <剑指Offer>P214(有序数组) <编程之美& ...

  6. java去除数组中重复的元素方法总结

    /* * ArrayUnique.java * Version 1.0.0 * Created on 2017年12月16日 * Copyright ReYo.Cn */ package reyo.s ...

  7. Java 向数组中添加一个元素

    方法 一般数组是不能添加元素的,因为他们在初始化时就已定好长度了,不能改变长度. 向数组中添加元素思路: 第一步:把 数组 转化为 集合 list = Arrays.asList(array); 第二 ...

  8. js面试题——找到数组中的重复元素并判断重复次数且输出重复元素

    var countArr = [1,2,3,4,5,6,3,4,3,3,7,8,9,32,1,11,2,3,3,3]; var res = {}; var maxnum=0; var max; fun ...

  9. LeetCode:1_Two_Sum | 两个元素相加等于目标元素 | Medium

    题目: Given an array of integers, find two numbers such that they add up to a specific target number. ...

随机推荐

  1. java中.equals和==的区别?

    Java中的equals是十分重要的,和= =要区别开来,孙卫琴的JAVA面向对象编程一书对这个做了阐述,现在小结其主要内容,而且要将 = =和 equals列为重要的对比概念来学习 1.声明格式   ...

  2. 6. Configure Compute services

    Controller Node: 1. sudo apt-get install nova-api nova-cert nova-conductor nova-consoleauth nova-nov ...

  3. Web中的图标

    随着时代的变迁与技术的不断的更新,在当今这个时代,Web中的图标(Icons)不再仅仅是局限于<img>.除了<img>直接调用Icons文件之外,还有Sprites(俗称雪碧 ...

  4. 【转】移动Web单页应用开发实践——页面结构化

    1. 前言 在开发面向现代智能手机的移动Web应用的时候,无法避免一个事实,就是需要开发单页应用(Single Page WebApp).对于不同的系统需求,单页应用的粒度会不同,可能是整个系统都使用 ...

  5. metasploit--payload模块信息

    Name                                             Disclosure Date  Rank    Description ----           ...

  6. 新浪SAEStorage图片上传的demo和说明

    <?php if(isset($_POST[up])){ $s2 =new SaeStorage();//实例化 $name =$_FILES['myfile']['name'];//上传到服务 ...

  7. HTTP 笔记与总结(5)socket 编程:使用 HTTP 协议模拟登录并发帖

    在 VeryCD 上注册两个帐号,发送和接收站内信,观察 POST 请求时发送的参数(h****2 发送给 d***2).(最好用 FireFox 的 FireBug 工具,发送站内信之前选中 “保持 ...

  8. PHP file_get_contents函数读取远程数据超时的解决方法

    PHP file_get_contents函数读取远程数据超时的解决方法 投稿:junjie 字体:[增加 减小] 类型:转载   这篇文章主要介绍了PHP file_get_contents函数读取 ...

  9. P1083 借教室

    思路:前缀和, c表示对于当前的middle, 前缀和 #include <bits/stdc++.h> using namespace std; const int maxn = 1e6 ...

  10. Mysql操作笔记(持续更新)

    1.mysqldump备份导出 备份成sql mysqldump -hlocalIp -uuserName -p --opt --default-character-set=utf8 --hex-bl ...