分治法求最大子陣列
阿新 • • 發佈:2022-12-05
最大子陣列(分治法)
解題思路:
將陣列分成兩份,最大子陣列(元素之和最大)只有三種情況:
- (1)最大子陣列在mid左邊,即:startIndex和endIndex都在mid左邊
- (2)最大子陣列一半在左邊,一半在右邊,即:startIndex在 mid左邊,endIndex在mid右邊
- (3)最大子陣列在mid右邊,即:startIndex和endIndex都在mid右邊
那麼比較三種情況下的最大子陣列的結果接可以了,最終得出最大子陣列
那麼繼續運用遞迴,繼續給mid左邊和右邊進行分治求解,將複雜的問題進行簡化,以此降低了程式碼的時間複雜度,提高了程式的執行效率。
程式碼實現
namespace _分治法求最大子陣列 { class Program { struct SubArray { public int startIndex; public int endIndex; public int total; } public static void Main(string[] args) { int[] priceArray = new int[] { 100, 120, 140, 50, 63, 89, 150, 162, 186, 20, 90, 48, 75, 97, 98 }; int[] priceFluctuationArray = new int[priceArray.Length - 1]; // 前後相減之後的差組成的陣列 for (int i = 1; i < priceArray.Length; i++) { priceFluctuationArray[i - 1] = priceArray[i] - priceArray[i - 1]; } SubArray subArray = GetMaxSubArray(0, priceFluctuationArray.Length - 1, priceFluctuationArray); Console.WriteLine(subArray.startIndex); Console.WriteLine(subArray.endIndex+1); } static SubArray GetMaxSubArray(int low, int high, int[] array) // 這個方法是用來取得array這個陣列從low到high之間的最大子陣列 { if (low == high) { SubArray subarray; subarray.startIndex= low; subarray.endIndex= high; subarray.total = array[low]; return subarray; } int mid = (low + high) / 2; // 地區間low到mid ,高區間mid+1 到high SubArray subArray1 = GetMaxSubArray(low, mid, array); SubArray subArray2 = GetMaxSubArray(mid + 1, high, array); // 從low-mid找到最大子陣列i-mid int total1 = array[mid]; int startIndex = mid; int totalTemp = 0; for(int i = mid; i >= low; i--) { totalTemp+= array[i]; if (totalTemp > total1) { total1 = totalTemp; startIndex = i; } } // 從mid-high找到最大子陣列mid+1-j int total2; total2 = array[mid+ 1]; int endIndex = mid + 1; totalTemp= 0; for(int j = mid + 1; j <= high; j++) { totalTemp+= array[j]; if(totalTemp> total2) { total2 = totalTemp; endIndex = j; } } SubArray subarray3; subarray3.startIndex = startIndex; subarray3.endIndex= endIndex; subarray3.total = total1 + total2; if (subArray1.total >= subArray2.total && subArray1.total >= subarray3.total) { return subArray1; } else if (subArray2.total >= subArray1.total && subArray2.total >= subarray3.total) { return subArray2; } else { return subarray3; } } } }