Java 找到数组中两个元素相加等于指定数的所有组合
思路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 找到数组中两个元素相加等于指定数的所有组合的更多相关文章
- java实现 数组中两个元素相加等于指定数的所有组合
package com.algorithm.hash; public class alg1 { public static void main(String argv[]) { int[] arr ...
- 交换数组中两个元素的位置,元素包括key和value 一维数组
/*author: yangyu@sina.cndescription: 交换数组中两个元素的位置,元素包括key和value,具体用法见下面的例子*/$arr = array(11=>'a', ...
- NlogN复杂度寻找数组中两个数字和等于给定值
算法导论:22页2.3-7 描述一个运行时间为O(nlogn)的算法,找出n个元素的S数组中是否存在两个元素相加等于给定x值 AC解: a=[1,3,6,7,9,15,29] def find2sum ...
- 2016网易实习生编程题:数组中两个数的和等于sum
题目 找出数组中两个数的和等于sum的这两个数 解题 这个题目做过很多次了,利用HashMap,key为 sum-A[i] value为 i 当 加入HashMap时候A[i] 已经存在map中,ge ...
- leetcode-1 Two Sum 找到数组中两数字和为指定和
问题描写叙述:在一个数组(无序)中高速找出两个数字,使得两个数字之和等于一个给定的值.如果数组中肯定存在至少一组满足要求. <剑指Offer>P214(有序数组) <编程之美& ...
- java去除数组中重复的元素方法总结
/* * ArrayUnique.java * Version 1.0.0 * Created on 2017年12月16日 * Copyright ReYo.Cn */ package reyo.s ...
- Java 向数组中添加一个元素
方法 一般数组是不能添加元素的,因为他们在初始化时就已定好长度了,不能改变长度. 向数组中添加元素思路: 第一步:把 数组 转化为 集合 list = Arrays.asList(array); 第二 ...
- 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 ...
- LeetCode:1_Two_Sum | 两个元素相加等于目标元素 | Medium
题目: Given an array of integers, find two numbers such that they add up to a specific target number. ...
随机推荐
- nova
chen@controller:~$ nova usage: nova [--version] [--debug] [--os-cache] [--timings] [--ti ...
- Objective-C、C++和swift 的运行效率比较
自己做iOS开发,以后慢慢都要转swift,前段时间看到网上的一个帖子,说swift的运行效率奇低,觉得自己有必要验证一下. 我用了一个最简单的加法运算,从0加到10000000,看三种语言的时耗. ...
- 移动端 :meta标签1万个作用
meta标签 <meta charset="utf-8"> <meta http-equiv="Content-Type" content=& ...
- shopnc编译安装IM服务器node.js
编译安装IM服务器node.js下载地址http://www.nodejs.org/download/ 选择Source Code node-v0.12.0 # ./configure # make ...
- linux查看时间和修改时间
查看当前时间,date -R 设置时间 date -s 例如当前时间2014年11月3日17:22:48 date -s 11/3/2014 date -s 17:22:48 先设置日期后设置具体时间 ...
- Frenetic QuickInstall
Frenetic a family of network programming languages 官方网站:Frenetic Github:Frenetic QuickInstall 第一步,先安 ...
- 【转载】wireshark:no interface can be used for capturing in this system with the current configuration
转自:wireshark:no interface can be used for capturing in this system with the current configuration 通过 ...
- ThinkPHP验证码刷新随机数
貌似因为IE的内核不支持重复,,所以要加个随机数..在代码中,,发现火狐的也不行..加了随机数后就可以了 <label class="img"><img id=& ...
- 1、C到C++安全性增强
1.C语言 #include <stdio.h> int main(void) { const int a = 10; //在C语言里这里不赋值可以编译的过去,但是这里不初始化以后就没办法 ...
- T-SQL 操作练习
create table Person #新建表格 ( Ids int auto_increment primary key, #主键,自增 Name ) not null, #非空 Age int, ...