由归并算法引申出来的其他问题
生活随笔
收集整理的這篇文章主要介紹了
由归并算法引申出来的其他问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言:
上一節剛講過歸并算法是排序算法中比較少見的一種時間復雜度為:θ(nlgn)的算法。而歸并算法之所以快的原因在于它用了分治的思想,現實生活中有很多需要用到分治思想解決的問題,下面就舉兩個例子。
?
問題一:
給定一個整數數組和任意整數,找到數組中是否有兩數的和等于給定的整數。
這個問題如果采用窮舉法,則大致思路是這樣:首先數組的第一個元素與數組剩下的元素相加,看是否有對應的結果。然后再數組第二個元素與除第一個元素和第二個元素本身之外的元素相加... 后面的操作一次類推。很容易得到時間復雜度為:(n-1) + (n-2) + ... + 1 =?θ(n2) 。 但其實我們可以借鑒前面歸并排序的思想,先對數組進行排序,排完序之后在進行和判斷,這時候只要收尾兩端各取一個數。如果兩數之后大于要找的數,則說明尾數應該前移,如果小于要找的數,則說明前面的數應該后移,如果相等則輸出找到的信息,并且避免死循環可以將前一個數后移或者后一個數前移。
java代碼如下:
1 public class FindEqualSum { 2 3 public static void main(String[] args) { 4 int[] arr = { 2, 1, 21, 16, 32, 35, 45, 31 }; 5 findEqualSum(arr, 33); 6 } 7 8 private static void findEqualSum(int[] arr, int num) { 9 int startIndex = 0; 10 int endIndex = arr.length - 1; 11 12 // 先進行歸并排序,然后再找兩數之和 13 divideSort(arr, startIndex, endIndex); 14 findInSorted(arr, startIndex, endIndex, num); 15 } 16 17 private static void divideSort(int[] arr, int startIndex, int endIndex) { 18 if (startIndex >= endIndex) { 19 return; 20 } 21 int midIndex = (startIndex + endIndex) / 2; 22 divideSort(arr, startIndex, midIndex); 23 divideSort(arr, midIndex + 1, endIndex); 24 merge(arr, startIndex, midIndex, endIndex); 25 } 26 27 private static void findInSorted(int[] arr, int startIndex, int endIndex, 28 int num) { 29 int i = startIndex; 30 int j = endIndex; 31 while (i < j) { 32 if (arr[i] + arr[j] > num) { // 如果兩數之和大于要找的數說明有一個數過大,這時候需要前移后面較大的數 33 j--; 34 } else if (arr[i] + arr[j] < num) { // 如果兩數之和小于要找的數,說明有一個數要小,這時應該后移前面較小的數 35 i++; 36 } else { // 相等這輸出找到的信息,這時候如果需要找到所有需要記住仍要前移后一個數或者后移前一個數,防止死循環。 37 System.out.println(arr[i] + " + " + arr[j] + " = " 38 + (arr[i] + arr[j])); 39 j--; 40 } 41 } 42 } 43 44 private static void merge(int[] arr, int startIndex, int midIndex, 45 int endIndex) { 46 int k = 0; 47 int i = startIndex; 48 int j = midIndex + 1; 49 int[] newArr = new int[endIndex - startIndex + 1]; 50 while (i <= midIndex && j <= endIndex) { 51 if (arr[i] > arr[j]) { 52 newArr[k++] = arr[j++]; 53 } else { 54 newArr[k++] = arr[i++]; 55 } 56 } 57 58 if (i <= midIndex) 59 { 60 System.arraycopy(arr, i, newArr, k, midIndex - i + 1); 61 } 62 if (j <= endIndex) 63 { 64 System.arraycopy(arr, j, newArr, k, endIndex - j + 1); 65 } 66 System.arraycopy(newArr, 0, arr, startIndex, endIndex - startIndex + 1); 67 } 68 69 } FindEqualSum.java?
??
問題二:
假設數組A[n],對于其中的A[i]和A[j],如果i<j, A[i] > A[j].則稱兩個元素為數組中的逆序對。求任意給定數組的所有逆序對。
同樣的道理:可以通過歸并排序的排序過程來進行逆序判斷,只要在merge的過程中進行對比就行了。
1 private static void merge(int[] arr, int startIndex, int midIndex, 2 int endIndex) { 3 int k = 0; 4 int i = startIndex; 5 int j = midIndex + 1; 6 int[] newArr = new int[endIndex - startIndex + 1]; 7 while (i <= midIndex && j <= endIndex) { 8 if (arr[i] > arr[j]) { 9 count++; // 這里用來記錄逆序對的個數 10 newArr[k++] = arr[j++]; 11 } else { 12 newArr[k++] = arr[i++]; 13 } 14 } 15 16 if (i <= midIndex) 17 { 18 System.arraycopy(arr, i, newArr, k, midIndex - i + 1); 19 } 20 if (j <= endIndex) 21 { 22 System.arraycopy(arr, j, newArr, k, endIndex - j + 1); 23 } 24 System.arraycopy(newArr, 0, arr, startIndex, endIndex - startIndex + 1); 25 } FindReverse?
黎明前最黑暗,成功前最絕望!總結
以上是生活随笔為你收集整理的由归并算法引申出来的其他问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TechInsights:折叠屏手机市场
- 下一篇: Silverlight 5 beta新特