最大子数组-分治算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36718838/article/details/81977575

参考自SIKI学院 C#编程第五季

求股市涨幅最大的期间

1.暴力求解

namespace Code5
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] priceArray = { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106,     
                               101, 79, 94, 90, 97 };
            //13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7
            int[] pf = new int[priceArray.Length - 1];//价格波动的数组
            for (int i = 1; i < priceArray.Length; i++)
            {
                pf[i - 1] = priceArray[i] - priceArray[i - 1];//计算两天股价差值
            }

            int total = pf[0];//先默认第一个元素是最大子数组
            int startIndex = 0;
            int endIndex = 0;
            for (int i = 0; i < pf.Length; i++)
            {
                //取得以i为子数组起点的所有子数组
                for (int j = i; j < pf.Length; j++)
                {
                    int totalTemp = 0;//存当前子数组的和
                    for (int index = i; index < j + 1; index++)
                    {
                        totalTemp += pf[index];
                    }
                    if (totalTemp > total)//如果比total大,赋值,记录索引
                    {
                        total = totalTemp;
                        startIndex = i;
                        endIndex = j;
                    }
                }
            }
            Console.WriteLine("startindex: " + startIndex);
            Console.WriteLine("endindex  : " + endIndex);
            Console.WriteLine("购买第" + startIndex + "天,出售第" + (endIndex + 1) + 
                                "天");
        }
    }
}

2.分治算法

[low,high],mid是中间索引,可以分为低区间[low,mid]和高区间[mid+1,high];

假设i,j为最大子数组的开始索引和结束索引,有三种情况。

1、i j 都位于低区间(递归)

2、i j 都位于高区间(递归)

3、i 位于低区间,j 位于高区间(循环)

namespace Code5
{
    class Program
    {
        //最大子数组结构体
        struct SubArray
        {
            public int startIndex;
            public int endIndex;
            public int total;
        }
        // 取得array数组 从low到high之间的最大子数组
        static SubArray GetMaxSubArray(int low, int high, int[] array)
        {
            if(low==high)//递归终止条件,low=high
            {
                SubArray subarray;
                subarray.startIndex = low;
                subarray.endIndex = high;
                subarray.total = array[low];
                return subarray;
            }

            int mid = (low + high) / 2;//中间数
            SubArray subArray1 = GetMaxSubArray(low, mid, array);//第一种情况
            SubArray subArray2 = GetMaxSubArray(mid + 1, high, array);//第二种情况

            int totalLow = array[mid];
            int totalTemp = 0;
            int startIndex = mid;
            //第三种情况
            //从[low,mid]
            for(int i=mid;i>=low; i--)
            {
                totalTemp += array[i];
                if(totalTemp> totalLow)
                {
                    totalLow = totalTemp;
                    startIndex = i;
                }
            }
            //从[mid+1,high]
            int totalHigh = array[mid + 1];
            int endIndex = mid + 1;
            totalTemp = 0;
            for(int j=mid+1;j<high+1;j++)
            {
                totalTemp += array[j];
                if(totalTemp> totalHigh)
                {
                    totalHigh = totalTemp;
                    endIndex = j;
                }
            }

            SubArray subArray3;
            subArray3.startIndex = startIndex;
            subArray3.endIndex = endIndex;
            subArray3.total = totalLow + totalHigh;
            if(subArray1.total>=subArray2.total&&subArray1.total>=subArray3.total)
            {
                return subArray1;
            }
            else if(subArray2.total >= subArray1.total && subArray2.total >= 
                    subArray3.total)
            {
                return subArray2;
            }
            return subArray3;
        }
        static void Main(string[] args)
        {
            int[] priceArray = { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 
            101, 79, 94, 90, 97 };
            //13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7
            int[] pf = new int[priceArray.Length - 1];//价格波动的数组
            for (int i = 1; i < priceArray.Length; i++)
            {
                pf[i - 1] = priceArray[i] - priceArray[i - 1];//计算差值
            }
            SubArray subArray=GetMaxSubArray(0, pf.Length - 1, pf);//调用分治算法方法

            Console.WriteLine("startindex   " + subArray.startIndex);
            Console.WriteLine("endindex     " + subArray.endIndex);
        }


    }
}

猜你喜欢

转载自blog.csdn.net/qq_36718838/article/details/81977575