面试算法题:数组中两个数之和为定值,找出这对数的下标
2016-11-16 14:46
176 查看
题目
已知一个数是一个数组中两个数据之和,找出这个数组中某一对符合条件的数例如:a[]={1,2,3,5,8} n=10,则输出{2,8}
思路
最笨的办法就是从第一个数开始,依次和后面的数相加,然后与n进行比较。如果相等则输出。时间复杂度o(n2)然而如果这个数组是有序数组呢?首尾两个数x,y相加和n比较,如果和比n大,说明后面的数太大了,y再取倒数第二大的数,如果和小,证明x太小了,取倒数第二小的数,如果等于n就输出。时间复杂度o(n)
加上排序的平均时间复杂为n(nlogn)比o(n2)小。可取。然后还有个问题就是排序会造成下标错误,这里我们用一个map来存储key=a[i],value=i,这样就可以根据数据来获取下标了。
ps:当时面试时候我想到的是:两个数的和为定值,则一定有一个数小于等于n/2(这个条件在面试时一直困惑了我,不知道有没有算法可以从这个地方入手,求大神指点,我是到面试结束都没想到但也不愿意放弃,so当时没做出来。)
代码:
public static void find() { int N = 35; int array[]={ 1, 2, 7, 9, 13, 57, 36, 26, 55, 11, 9, 6, 3, 89, 36, 75, 36, 76, 95, 98, 101, 320, 520, 85, 36, 62, 49, 96, 1 }; Map<Integer,Integer> hs=new HashMap<Integer,Integer>(); for (int i = 0; i < array.length; i++) { hs.put(array[i], i); } Arrays.sort(array); int s1=-1,s2=-1,i=0,j=array.length-1; int addAns; //比较,如果addAns>0表示 时间复杂度o(n) while((addAns=array[i]+array[j]-N)!=0&&i<j){ if(addAns>0){ j--; }else{ i++; } } if(i==j){ System.out.println("没有结果"); return; } //找到其中一组下标 System.out.println("any one: "+hs.get(array[i]) + ":" + array[i] + "+" + hs.get(array[j]) + ":" + array[j]); }
扩展一下
如果要找到出现的第一组下标以及数值呢?我们可以不用hashmap而用数组来存储,最后再根据两个数值去遍历数组找到他们第一次出现的位置。
代码
public static void find() { int N = 35; int array[]={ 1, 2, 7, 9, 13, 57, 36, 26, 55, 11, 9, 6, 3, 89, 36, 75, 36, 76, 95, 98, 101, 320, 520, 85, 36, 62, 49, 96, 1 }; int array1[]=array.clone(); Map<Integer,Integer> hs=new HashMap<Integer,Integer>(); for (int i = 0; i < array.length; i++) { hs.put(array[i], i); } Arrays.sort(array); int s1=-1,s2=-1,i=0,j=array.length-1; int addAns; //比较,如果addAns>0表示 时间复杂度o(n) while((addAns=array[i]+array[j]-N)!=0&&i<j){ if(addAns>0){ j--; }else{ i++; } } if(i==j){ System.out.println("没有结果"); return; } //找到其中一组下标 System.out.println("any one: "+hs.get(array[i]) + ":" + array[i] + "+" + hs.get(array[j]) + ":" + array[j]); //找到第一组下标 时间复杂度o(n) for(int k=0;k<array1.length-1;k++){ if(array1[k]==array[i]&&s1<0){ s1=k; } if(array1[k]==array[j]&&s2<0){ s2=k; } if(s1>=0&&s2>=0) { break; } } System.out.println("first one: "+s1 + ":" + array[i] + "+" + s2 + ":" + array[j]); }
最后,同样的如果您有更方便快捷的算法,欢迎打脸哦~
相关文章推荐
- 如何找出数组中第二大的数?(一道面试算法题的思考)
- 在给定数组中,找出最先满足两个数的和等于给定数,输出这两个元素的下标
- 算法3:找出一个整数数组里面两个查值最大的两个下标a[j]-a[i]最大并且i<j
- 从一个数据元素无序的整型数组中找出最小的两个数的下标
- 算法---从一个数组(或者集合中)找出和为某个值的下标
- 小小c#算法题 - 1 - 找出数组中满足条件的两个数
- 算法题(一)--找出数组中第k大的数并输出其下标(数组中的数有重复)
- 【算法世界】(八)找出数组中的两个数,使得二者之和为特定值target
- 面试-算法 已经排好序的数组中求两个数的和等于N
- 面试算法题:从指定数组找出两数的和为指定的数
- 常见面试算法题:给定数组中寻找加和为特定数的两个数
- 一个数组中两个数的和为N,找出这两个数字的下标
- 【查找】在按照绝对值排序的数组中,找出和为k的两个数的下标
- 一个无序整数数组,数组元素大于5个,请用一种高效的算法找出其中最大的5个值.
- 每天一道算法题-1 找出数组中两个只出现一次的数字
- 每天学习一算法系列(14) (输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字)
- 现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数
- 5-8: 输入一个5行、6列的数组,找出该数组中绝对值最大的元素,输出该元素及其两个下标值
- 算法--找出数组中出现次数超过一半的数
- 数组a[n]中存放1-n中的n-1个数,给出算法找出重复的那一个数