LeetCode Two Sum
2015-05-06 09:52
387 查看
Given an array of integers, find two numbers such that they add up to a specific target number.The function twoSum should return result of the two numbers such that they add up to the target . Please note that your returned answers (both result1 andresult2) are not zero-based.You may assume that each input would have exactly one solution.Input: numbers={2, 7, 11, 15}, target=9Output: result1=2, result2=7一:若数组无序方法一,使用双重循环,遍历数组的方法,确定一个数之后查找数组以确定另外一个数是否也存在数组中
/*2: * 寻找和为定值的两个数 * 问题描述:给定一个数组和一个数,要求在数组中找出两个数,使其和为该数,并输出这两个数 * * 方法一:该算法的时间复杂度为o(n*n),双重循环 * 分析: * 1,给定无序数组T,整数k * 2,i=0->T.length int temp=k-T[i] * 3,j=i+1->T.length if(temp==T[j]) return T[I],T[j] * @param Targent目标无序数组 * @param k和值 * @param 返回值为一个数组,存放结果的两个数 */ public int[] twoSum1(int[] Targent,int k){ int[] result=new int[2]; int temp=0; for(int i=0;i<Targent.length;i++){ temp=k-Targent[i]; //第一个数确定的情况下,求出第二个数 for(int j=1+i;j<Targent.length;j++){ if(temp==Targent[j]){ //在数组中寻找第二个数是否存在,若存在,则返回两个数 result[0]=Targent[i]; result[1]=Targent[j]; return result; } } } return result; }方法二,使用hashmap映射的方法
/* * 方法四:利用hashMap存放互补数组,将原数组和互补数组作映射,查找hashMap的时间复杂度为O(1),与处理hashMap的时间 * 复杂度为O(n),故该方法的时间复杂度为O(n),但是需要O(N)的hashMap空间复杂度,在时间复杂度要求比较高的情况下,可以利用 * 空间换时间! * 伪代码: * 1,int[] T,int k int[] R=k-T[i] i=0->T.length * 2,hashMap.put(k-T[i],T[i]) i=0->T.length-1 //构造hashMap,key=k-T[i],value=T[i] ,时间复杂度为O(n) * 3,if(hashMap.containsKey(T[i])) return T[i],k-T[i]; //containsKey(key)根据hashMap中是否存在键值,来返回 * @param Targent为无序或者有序数组 * @param k为输入和值 * @param 返回值为二维数组 */ public int[] twoSum4(int[] Targent,int k){ int[] result=new int[2]; //构造hashMap Map<Integer, Integer> reflectMap=new HashMap(); for(int i=0;i<Targent.length;i++){ //将数组R作为key值,T作为value,时间复杂度为O(n) reflectMap.put(k-Targent[i], Targent[i]); } //根据T[i]查询hashMap,hashMap查询时间复杂度为O(1) for(int i=0;i<Targent.length;i++){ if(reflectMap.containsKey(Targent[i])){ result[0]=Targent[i]; result[1]=k-Targent[i]; return result; } } return result; }二:若数组按照升序排列方法一,在循环遍历的基础上使用二分查找,确定一个数之后,使用二分查找另外一个数是否存在于数组之中
/** 算法优化:二分查找的时间复杂度为O(lgn),最坏情况下需要查找n次,故该算法的时间复杂度为O(nlgn)* 若数组无序,则用快速排序方法进行排序,时间复杂度为O(nlgn),最后总共的时间复杂度为O(nlgn)+O(nlgn)=O(nlgn)* 分析:* 1,int i=0->T.length int temp=k-T[i]* 2,使用二分查找的方法来寻找temp数值是否在T数组中* @param Targent为有序数组* @param k为输入和值* @param 返回值为二维数组*/public int[] twoSum2(int[] Targent,int k){int[] result=new int[2];int temp=0;for(int i=0;i<Targent.length;i++){ //时间复杂度O(n)temp=k-Targent[i];if(divideQuery(Targent, temp)){ //时间复杂度O(lgn)result[0]=Targent[i];result[1]=temp;return result;}}return result;}/** 二分查找:递归实现,时间复杂度为O(lgn)* 分析:* 1,对于一个有序数组T,所需要查找的数为k* 2,int index = (T.length-1)/2 //找到数组中位数的下标指针* 3,boolean divideQuery'(int[] Targent, int k, int left, int right)* if(k<T[index]) return divideQuery(T, k , 0 ,index-1)* else if(k==T[index]) return true* else return divide Query(T, k, index+1, T.length-1)* 4,if(left==index&&Targent[index]!=k) return false; //递归结束判断* @param Targent目标有序数组* @param k需要查找的数* @param 返回值为boolean ,存在k则返回true ,否则返回false*/public boolean divideQuery(int[] Targent,int k) {int firstIndex=Targent.length-1;if(k<Targent[0]||k>Targent[firstIndex])return false;return divideQuery(Targent, k, 0 , firstIndex);}private boolean divideQuery(int[] Targent, int k ,int left ,int right) {int index=(right+left)>>1;//该判断为递归结束的判断条件,否则递归不能结束if(left==index&&Targent[index]!=k)return false;if(k<Targent[index])return divideQuery(Targent, k, left, index-1);else if(k==Targent[index])return true;elsereturn divideQuery(Targent, k, index+1, Targent.length-1);}/** 二分查找:while循环实现,对于有序数组时间复杂度为O(lgn)* 伪代码:* 1,int left=0,right=T.length-1* 2,int index=(left+right)>>1* 3,while(left!=right){* if(T[index]>k){ //若中位数比k大,则说明k在中卫数之前,需要将right指针左移一位* right=index-1;* index=(left+right)>>1;}* else if(T[index]==k) //若中位数与k相等,则返回找到* return true* else{ //若中位数比k小,则说明k在中位数后面,需要将left指针加一* left=index+1* index=(left+right)>>1}* }* @param Targent目标有序数组*/public boolean divideQuery2(int[] Targent,int k){int left=0;int right=Targent.length-1;int index=(right+left)>>1;//此处找到循环条件需要注意left<=right为正确,不能选择left!=right否则//当查找到left==right时,循环结束,该条件下没有判断while(left<=right){if(Targent[index]>k){//注意找到中位数之后,right指针需要变动right=index-1;index=(left+right)>>1;}else if(Targent[index]==k)return true;else{//注意找到中位数之后,left指针需要变动left=index+1;index=(left+right)>>1;}}return false;}方法二,可以使用求互补数组的方法,对于升序排列的数组,求出其互补数组,若存在两个数相加等于目标数,则在这两个数组之中一定存在相等的两个数。
/** 求互补数组的方法* 算法时间复杂度为O(n),但是需要求出互补数组,故空间复杂度为O(n)* 1,若有序数组T中存在两个数a,b 使得a+b=k成立* 2,作数组D=k-T[i],则a,b两数一定在数组D中存在* 3,定义两个整形变量i,j,使i从T数组左边开始遍历,j从D数组右边开始遍历,若找到相等的数,则返回找到,一直到i=j* 例如,若数组T={1,2,4,7,11,15},若k=15,则数组D={14,13,11,8,4,0},4+11=15成立,故若4在数组T中,则在D中也一定存在* 伪代码:* 1,int T,* 2,int D=k-T[i] i=0->T.length;* 3,while(i!=j)* if(T[i]>D[J])* J++;* if(T[i]==D[j])* return T[i],k-T[i]* if(T[i]<D[j])* i++* return -1* @param Targent为无序或者有序数组* @param k为输入和值* @param 返回值为二维数组*/public int[] twoSum3(int[] Targent,int k){int[] result=new int[2];//计算数组T的差分数组,时间复杂度为O(n)int[] minus=new int[Targent.length];for(int i=0;i<Targent.length;i++){minus[i]=k-Targent[i];}//定义两个指针int i=0;int j=Targent.length-1;while(i!=j){ //时间复杂度为O(n),遍历指针i+j<=nif(Targent[i]==minus[j]){result[0]=Targent[i];result[1]=k-Targent[i];return result;}if(Targent[i]>minus[j])j--;if(Targent[i]<minus[j])i++;}return result;}方法三,该算法在升序排列的基础上,为最好的算法。
/** 最好的算法,* 要求数组为有序数组,此时时间复杂度为O(n),否则先进行排序,时间复杂度为O(NLGN)+O(N)* 寻找时间复杂度为O(N),空间复杂度为O(1)的算法* 分析:* 1,对于数组T,若数组无序,则首先对数组进行排序,时间复杂度为O(nlgn)* 2,定义两个指针,left=0,right=T.length-1分别从数组的两端遍历数组* 3,若T[left]+T[right]>K,则使right指针左移一位,减小两个数的和值* 4,若T[left]+T[right]<K,则使left指针右移一位,增加两个数的和值* 5,当指针left=right时,结束循环判断* @param Targent为有序数组* @param k为输入的数* @param 返回值为一个二维数组*/public int[] twoSum5(int[] Targent,int k){//定义存放结果的数组int[] result=new int[2];//定义两个指针int left=0;int right=Targent.length-1;//循环控制,判断T[left]+T[right]与K值的大小while(left<right){if(Targent[left]+Targent[right]>k)right--;else if(Targent[left]+Targent[right]<k)left++;else {result[0]=Targent[left];result[1]=Targent[right];return result;}}return result;}
相关文章推荐
- Two Sum--LeetCode
- [leetcode]: 1. Two Sum
- 【LeetCode】第1题: Two Sum
- Leetcode 1. Two Sum
- leetcode之Two Sum
- LeetCode - Two Sum 完整代码(GO)
- 【leetcode】【1】Two Sum
- leetcode No.1 Two Sum
- leetcode------第一题 Two Sum
- LeetCode-Two Sum
- leetcode-Two Sum
- LeetCode 1.Two Sum
- leetcode 刷题题解(c++) 1.Two Sum (hash表,排序+二分查找)
- [leetcode 1] Two Sum
- LeetCode 01 Two Sum
- leetcode之Two Sum
- leetcode 1 -- Two Sum
- LeetCode|Two Sum
- [Leetcode]之一《two sum》解题报告
- [LeetCode] Two Sum