1. 程式人生 > 其它 >分治法求最大子陣列

分治法求最大子陣列

最大子陣列(分治法)

解題思路:

將陣列分成兩份,最大子陣列(元素之和最大)只有三種情況:

  • (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;

            }

        }

    }

}