思路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. 《GK101任意波发生器》升级固件发布(版本:1.0.2build539)

    一.固件说明: 硬件版本:0,logic.3 固件版本:1.0.2.build539 编译日期:2014-10-08 ====================================== 二. ...

  2. spring redis整合

    1,利用spring-data-redis整合 项目使用的pom.xml: <project xmlns="http://maven.apache.org/POM/4.0.0" ...

  3. thrift

    环境准备: 1.下载window版本的thrift编译器 2.下载idea的thirft插件 3.设置thrift编译工具为:步骤1下载的编译器 4.编写thrift文件 namespace java ...

  4. 每天学点GDB 11

    为了跟踪glibc库中函数的执行,需要带有debug symbol的glibc, 如果是debian或者是基于debian的发行版本如ubuntu和linuxmint之类的,很简单执行如下指令安装即可 ...

  5. PHP 错误与异常 笔记与总结(15 )使用观察者模式处理异常信息

    使异常处理变得更灵活.可观察,可以使用设计模式中的观察者模式. 文件 ① 定义观察者的接口 ExceptionObserver.php: <?php /* 给观察者定义的规范 */ interf ...

  6. spring mvc传入参数不仅仅转换为json,还可以直接将json字符串转换为具体的java对象

    1.controller层 /** * 查看主播资料 * * @return */ @RequestMapping(value = { "/actor_details" }, me ...

  7. SqlServer 高版本数据库 降级

    SQL Server2012 1 首先就来介绍一下SQL Server2012数据库的降级方法,成功之后突然感觉很简单,但是没成功之前很郁闷.废话少说,直接开始. 打开SQL Server2012,连 ...

  8. MySQL线程独享[转]

    一.前言在 MySQL 中,线程独享内存主要用于各客户端连接线程存储各种操作的独享数据,如线程栈信息,分组排序操作,数据读写缓冲,结果集暂存等等,而且大多数可以通过相关参数来控制内存的使用量。 二.线 ...

  9. Mysql 定时备份操作

    1.创建保存备份文件的路径/mysqldata #mkdir /bak/mysqlbak 2.创建/usr/sbin/bakmysql文件 #vi /usr/sbin/bakmysql.sh 3.写入 ...

  10. LAMP环境搭建教程(原创)

    学习PHP脚本编程语言之前,必须先搭建并熟悉开发环境,开发环境有很多种,例如LAMP.WAMP.MAMP等.这里我介绍一下LAMP环境的搭建,即Linux.Apache.MySQL.PHP环境. 一. ...