分治法求最大子数组

最大子数组(分治法)

解题思路:

将数组分成两份,最大子数组(元素之和最大)只有三种情况:

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

            }

        }

    }

}

posted @ 2022-12-05 17:24  xiaoliangliang  阅读(140)  评论(0编辑  收藏  举报