An array of algorithm questions and solving arrays and problems
? Plus given an array and a value of x. An algorithm is designed so that if there are two elements in the array and x, then the output of the two elements of the array (without distinction), otherwise output {-1,-1}.
? Analysis:
- The simplest way to do this is to ask each element and the other elements in turn. This is the classic handshake problem, it is not difficult to conclude that the worst time complexity is: \ (\theta\)(\ (n^2\)) This exponential level of time complexity is not what we want, direct pass
- Sort and then look: assuming that the fastest sorting algorithm previously known is used, the worst-case complexity is: \ (\theta\)(NLG (n)). You can then use the binary lookup method to find X-arr[i] for each element in the array, at which time the worst time complexity is: \ (\theta\)(NLG (n)). The algorithm implements the following code:
Private Static int[]Findsum(int[] arr,intSUM) {//STEP1: Sort the array by merge sort MergeSort(Arr,0, arr.length);///STEP2: Iterate through an array and find the element with a binary lookup for the presence of Sum-arr[i] for(intI=0; I<arr.length; i++) {intj =BinarySearch(Arr,0, arr.length, Sum-arr[i]);if(J! =-1) {if(J! = i) {return New int[] {arr[i], arr[j]}; }Else{//J = i, you need to determine whether the left and right values of J are equal to J, and the equivalent proves that there are two elements if(Arr[j-1] = = Arr[j]) {return New int[] {arr[i], arr[j-1]}; }Else if(Arr[j +1] = = Arr[j]) {return New int[] {arr[i], arr[j +1]}; } } } }return New int[]{-1, -1}; }
Note that mergesort and BinarySearch invoke the code http://www.cnblogs.com/Kidezyq/p/8379267.html referred to in the previous section.
Extended
- In fact, for the two elements and there is a time complexity is:\ (\theta\)(n) algorithm. The algorithm uses the idea of bucket sequencing, with the help of the special data structure of map. Here we take arr[i] as value for key,i. To determine if sum-arr[i] exists in the array, just see if Map.get (Sum-arr[i]) is empty. The implementation code is as follows:
Private Static int[]Findsumwithmap(int[] arr,intSum) {Map<integer, integer> Map =NewHashmap<> ();//STEP1: Data into Map for(inti =0; I < arr.length; i++) {map.put(Arr[i], i); }//STEP2: Start judging whether Sum-arr[i] is in map for(inti =0; I < arr.length; i++) {//Because the order in which the traversal is placed in the map is from front to back, if there are multiple elements of the same value, it will eventually place the subscript in the map, without affecting the judgment logic if(Map.Get(Sum-arr[i])! =NULL&& i! = map.Get(Sum-arr[i])) {return New int[]{arr[i], sum-arr[i]}; } }return New int[]{-1, -1}; }
- In fact, for the above analysis Method 2, there is an optimized method, you can find the sorted array in time:\ (\theta\)(n) within the two and for the specified value of the algorithm. Method of thinking or binary search method. First Take two bottom lowindex and Upindex, at the beginning of the Lowindex point to the first element of the array, Upindex points to the end of the array element. Then compare the relationship of Arr[lowindex] + Arr[upindex] with sum. The Lowindex and Upidex were moved according to the results of the comparison. You only need \ (\theta\)(n) time to follow the entire lookup process at this point. The source code is as follows:
Private Static int[]Findsumtwoside(int[] arr,intSUM) {//STEP1: Use merge sort to sort the array MergeSort(Arr,0, arr.length);//STEP2: Search both ends intLowindex =0;intUpindex = arr.length-1; while(Upindex > Lowindex) {if(Arr[lowindex] + arr[upindex] = = SUM) {//Equal direct return return New int[] {Arr[lowindex], Arr[upindex]}; }Else if(Arr[lowindex] + Arr[upindex] < sum) {//Less than left right shiftlowindex++; }Else{//greater than right left shiftupindex--; } }return New int[] {-1, -1}; }
- The problem can be extended to the sums of n elements:
The solution of the idea is to divide and conquer. The size of the n elements is reduced in turn, resulting in a decrease of 2 elements. This gives an example of the sum of three elements, and the other multidimensional in turn:
Private Static int[]findsumof3digits(int[] arr,intSUM) {///STEP1: Sort by calling merge sort algorithm first MergeSort(Arr,0, arr.length);//STEP2: Fine-grained problem handling //Apply an array first to store a new array of elements that exclude an element after the array int[] Leftarr =New int[Arr.length-1]; for(inti =0; I < arr.length; i++) {//Copy arr[i] left element to array start position if(I >0) {System.arraycopy(Arr,0, Leftarr,0, i); }//Copy arr[i] Right element to end of array position if(I < arr.)length-1) {System.arraycopy(arr, i +1, Leftarr, I, arr.lengthI1); }//If the remaining two numbers are satisfied, then three elements are returned int[] leftindexes =Findsumtwoside(Leftarr, sum-arr[i]);if(! Arrays.equals(Leftindexes,New int[] {-1, -1})) {return New int[] {arr[i], leftindexes[0], leftindexes[1]}; } }return New int[] {-1, -1, -1}; }
Array and problem of the algorithm