数组中寻找和为X的两个元素
题目描述:给定一个数组,判断是否能从中寻找到两个元素,它们的和为给定的值X。
分析:假定数组长度为n,寻找两个元素和为特定值,我们完全可以用两个循环将数组中每两个元素相加,然后依次判断是否等于特定值。由于套用了两层循环,所以这个算法的时间复杂度为o(n2)。那么有没有时间复杂度更低的算法呢?
我们可以这样想,假如这个数组是有序的,即升序或者降序排列,那么我们只需要不断比较第一个与最后一个数值和和给定数值,根据大小移动第一个下标或者第二个。由此我们可以先把这个数组进行排序,然后再进行查找。排序算法可以选择快速排序,它能在O(nlogn)的时间复杂度内将元素排列好。想到这里,我们就可以开始编写代码了。
1 public class FindOut { 2 public static boolean hasTwo(int[] array, int x) { 3 int length = array.length; 4 QuickSort.quickSort(array, 0, length-1); 5 6 if(array[0] >= x){ 7 return false; 8 } 9 int i = 0; 10 --length; 11 while(i < length){ 12 if(array[i] + array[length] == x){ 13 return true; 14 }else if(array[i] + array[length] > x){ 15 --length; 16 }else{ 17 ++i; 18 } 19 } 20 return false; 21 } 22 23 public static void main(String[] args) { 24 int[] array = {2,8,7,1,3,5,6,4,12,0}; 25 System.out.println(hasTwo(array, 10)); 26 } 27 28 }
代码中QuickSort.quickSort(array, 0, length-1);这一行我调用了已经写好的快速排序的代码。对快速排序不是很理解的可以转去快排 (C++)的详解。
在这里为了方便,也贴出Java版本的快速排序。这个版本在寻找轴的算法中与C++略有不同,大家可以仔细考虑一下。
1 public class QuickSort { 2 3 public static int findPrivote(int[] array, int low, int high) { 4 int temp = array[low]; 5 while(low < high){ 6 while(low < high && array[high] > temp){ 7 --high; 8 } 9 array[low] = array[high]; 10 while(low < high && array[low] < temp){ 11 ++low; 12 } 13 array[high] = array[low]; 14 } 15 array[low] = temp; 16 return low; 17 } 18 19 public static void quickSort(int[] array, int low, int high){ 20 if(low < high){ 21 int privote = findPrivote(array, low, high); 22 quickSort(array, low, privote-1); 23 quickSort(array, privote+1, high); 24 } 25 } 26 27 public static void main(String[] args) { 28 int[] array = {2,8,7,1,3,5,6,4,12,0}; 29 quickSort(array, 0, array.length-1); 30 for (int i : array) { 31 System.out.println(i); 32 } 33 } 34 35 }