首页 > 代码库 > 编程之美2.12 快速寻找满足条件的两个数

编程之美2.12 快速寻找满足条件的两个数

问题描述:

能否快速找到一个数组中的两个数字,让这两个数字之和等于一个给定的数字,为了简化起见,我们假设这个数组中肯定存在这样一组或以上符合条件的解。这里我们只考虑一种解

的情况。

 

解法:

1. 暴力解法------O(n^2)

2. 排序+二分查找------O(nlogn)

3. hash表查找------O(n)

4. 排序+收尾相加移动法-------O(nlogn)

 

具体思路和代码:

1. 暴力解法------O(n^2)

思路:第一层循环控制一个变量A[i]不变,在另一层循环中查找Sum-A[i].

代码: 

 1 vector<int> s1(int A[], int n, int sum)
 2 {
 3     for(int i = 0; i < n; i++)
 4     {
 5         vector<int> v;
 6         v.push_back(A[i]);
 7         int m = sum - A[i];
 8         for(int j = 0; j < n; j++)
 9         {
10             if(A[j] == m)
11             {
12                 v.push_back(A[j]);
13                 return v;
14             }
15         }
16     }
17 }

 

 

2. 排序+二分查找------O(nlogn)

 

思路:先对数组进行排序(nlogn),

        然后固定住一个数值,利用二分查找的方式找到另一个(nlogn)

 

代码: 

 1 void exchange(int A[], int i, int j)
 2 {
 3     int temp = A[i];
 4     A[i] = A[j];
 5     A[j] = temp;
 6 }
 7 
 8 int partition(int A[], int p, int r)
 9 {
10     int x = A[r];
11     int i = p-1;
12     for(int j = p; j < r; j++)
13     {
14         if(A[j] <= x)
15         {
16             i++;
17             exchange(A, i, j);
18         }
19 
20     }
21     exchange(A, i+1, r);
22     return i+1;
23 }
24 
25 
26 void QuickSort(int A[], int p, int r)
27 {
28     if(p >= r)
29         return;
30     else
31     {
32         int t = partition(A, p, r);
33         QuickSort(A, p, t-1);
34         QuickSort(A, t+1, r);    
35     }
36     
37 }
38 
39 int binSearch(int A[], int p, int r, int o)
40 {
41     if(p > r)
42         return -1;
43 
44     int mid = (p + r) / 2;
45     if(o == A[mid])
46         return mid;
47 
48     else
49     {
50         if(o < A[mid])
51             return binSearch(A, p, mid-1, o);
52         else
53             return binSearch(A, mid+1, r, o);
54     }
55 
56 }
57 
58 vector<int> s2(int A[], int n, int sum)
59 {
60     for(int i = 0; i < n; i++)
61     {
62         vector<int> v;
63         v.push_back(A[i]);
64         int m = binSearch(A, 0, n-1, sum-A[i]);
65         v.push_back(A[m]);
66         return v;
67     }
68 }

 

 

 

3. hash表查找------O(n)

思路:空间换时间利用hash表将数据一一存储,这里涉及到hash函数的设计。

   第一层循环,固定住A[i].--------O(n)

        在hash表中查找Sum-A[i].-------O(1)

这边代码省略,主要是设计hash函数,怎样一一映射。

 

4. 排序+收尾相加移动法-------O(nlogn)

 

思路:先对数组进行排序(nlogn),

 

        然后对数值进行收尾相加,若和大于sum,尾巴往前移动。

                                  若和小于sum,头部往后移动。

代码:

 1 vector<int> s3(int A[], int n, int sum)
 2 {
 3     for(int i = 0, j = n-1; i <j;)
 4     {
 5         vector<int> v;
 6         if(A[i] + A[j] == sum)
 7         {
 8             v.push_back(A[i]);
 9             v.push_back(A[j]);
10         }
11         else
12         {
13             if(A[i] + A[j] > sum)
14                 j--;
15             else
16                 i++;
17         }
18         return v;
19     }
20 }