Quickly find two numbers in an array such that the sum of these two numbers is equal to a given value

The original address http://blog.csdn.net/hackbuteer1/article/details/6699642
Quickly find two numbers in an array, so that the sum of these two numbers is equal to a given value , for the sake of simplicity, we assume There must be at least one set of satisfactory solutions in this array.
If there are the following two arrays, as shown in the figure:
5 , 6, 1, 4, 7, 9, 8
given Sum= 10 1 , 5, 6, 7, 8, 9 given Sum= 10
Analysis and solution The subject is not difficult and easy to understand. But to come up with an efficient solution, it still takes some thinking. Solution 1 A straightforward solution is exhaustive: take two numbers arbitrarily from the array, and calculate whether the sum of the two is the given number. Obviously its time complexity is N(N-1)/2 or O(N^2) . The algorithm is simple and easy to write, but not very efficient. Generally, in program design, it is necessary to reduce the time and space complexity of the algorithm as much as possible, so it is necessary to continue to find more efficient solutions. Solution 2 Find the sum of two numbers, assuming the given sum is Sum. A workaround is to determine whether Sum-arr[i] is in the array for each number arr[i] in the array, so that it becomes a search algorithm. The complexity of finding a number in an unordered array is O(N) . For each number arr[i], you need to find the corresponding Sum-arr[i] in the array. It is easy to get the time complexity or O(N^2)








. This is no improvement over the most primitive method. But if the efficiency of search can be improved, the efficiency of the whole algorithm can be improved. How to improve the efficiency of search?
Anyone who has studied programming knows that to improve the search efficiency, the array to be searched can usually be sorted first, and then searched by methods such as binary search, which can shorten the original O(N) search time to O(log2N) , so that for each For each arr[i] , it takes O(log2N) to find the corresponding Sum-arr[i] in the array, and the total time complexity is reduced to N*log2N . When sorting an array of length N itself requires O(N*log2N) time, but fortunately it only needs to be sorted once, so the total time complexity is still O(N*log2N) . In this way, the most primitive method is improved.
At this point, some readers may further think that sorting first and then binary search can shorten the time from O(N^2) to O(N*log2N) , but there is a faster search method: hash table. Because given a number, it only takes O(1) time to find whether another number is in the array according to the hash table mapping. In this way, the overall algorithm complexity can be reduced to O(N) , but this method requires an additional O(N) hash table storage space. In some cases, exchanging space for time can be a good idea.
Solution three
You can also consider the problem from another angle, assuming that there is already an ordered array (length N^2) of the sum of any two elements of this array. Then using the binary search method, this problem can be solved with only O(2*log2N). Of course it is unlikely to compute this sorted array, since it takes O(N^2) time. But this thinking still inspires us to perform an ordered traversal directly on the sum of two numbers, thereby reducing the time complexity of the algorithm.
First sort the array, the time complexity is (N*log2N).
Then set i = 0, j = n-1, see if arr[i] + arr[j] is equal to Sum, and if so, end. If less than Sum, i = i + 1; if greater than Sum, then j = j – 1. In this way, you only need to traverse the sorted array once to get the final result, and the time complexity is O(N). The total time complexity of the two steps is O(N*log2N). The following program uses this idea. The code is as follows:
[cpp] view plain copy

int getSumNum(int[] arr,int Sum),   //arr为数组,Sum为和   
{  
     int i,j;  
     for(i = 0, j = n-1; i < j ; )  
     {  
         if(arr[i] + arr[j] == Sum)  
             return ( i , j );  
         else if(arr[i] + arr[j] < Sum)  
             i++;  
         else  
            j--;  
     }  
     return ( -1 , -1 );  
 }  
  它的时间复杂度是O(N)。
  刚开始一直无法理解这样一定可以找到这个和吗?难道不会漏掉了解的位置。可以这么理解,假如排好序后的数组为1,3,6,a,9,12,17,28,b,35,46  ,那么i最初指向1的位置,j最初指向46的位置,比如所求的是Sum=a+b,a

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325692072&siteId=291194637