问题、输入一个递增排序数组和一个数字s,在数组中查找两个数,使得它们的和正好是s,如果有多对数字的和等于s,输出任意一对即可。
显然,很快能想到的是使用蛮力法(O(n2)),先固定一个数字,再判断剩下的n-1个数字与它的和是否等于s。这种效率显然有点低,我们可以使用下面比较快的方式,时间复杂度O(n)。
思路:我们通过两个记录数组的开始位置和结束位置,从数组的尾部开始,求两个数字的和,
如果两个数的和大于我们需要求的数s,则后面的记录前移一位(因为是排好序的,前移一位,相当于数值减少),再进行判断,
如果两个数的和小于我们要求的数s,则前面的位置记录后移一位(因为是排好序的,后移一位,相当于数值增加),再进行判断,
直至找到或者后面或前面的位置记录重合。
代码实现:
/** * 输入一个递增排序数组和一个数字s,在数组中查找两个数,使得它们的和正好是s,如果有多对数字的和等于s,输出任意一对即可。因为java只能 * 有一个返回值,这里返回了真假,或者可以改成数组,返回查找到的两个数,这里就实现返回是否找到,如果找到就打印出来! * @param data 待查找的递增数组 * @param length 数组长度 * @param sum 要查找的和 * @return 是否查找成功! */ public static boolean FindNumberWithSum(int data[],int length,int sum) { boolean found = false; if(length < 1) { return found; } int ahead = length -1 ; //较大数字的下标 int behind = 0; //较小数字的下标 while(ahead > behind) { long curSum = data[ahead] + data[behind]; if(curSum == sum) { System.out.println("查找成功!两个数为:"+data[ahead]+"," + data[behind]); break; } else if(curSum > sum) { ahead -- ; } else { behind ++; } } return found; }
测试:
public static void main(String[] args) { int[] arr = {1,2,4,7,11,15}; FindSumEqualNum.FindNumberWithSum(arr,arr.length,15); }
结果:
查找成功!两个数为:11,4