最大子数组问题 - (暴力求解+分治法)

股票问题
这里写图片描述
1.暴力求解 2. 分治法

题目解析:根据价格的变化,求出股票在哪天买入哪天卖出,收益会最大。


暴力求解:遍历每一个子数组区间,比较大小,并记录最大收益的开始和结束的下标

代码实现:

using System;

namespace cchoop
{
    class Program
    {
        public static void Main()
        {
            int[] price = new int[] { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
            int[] priceChange = new int[price.Length - 1];
            for (int i = 1; i < price.Length; i++)
            {
                priceChange[i - 1] = price[i] - price[i - 1];
            }

            int sum = priceChange[0];
            int startIndex = 0;
            int endIndex = 0;

            for (int i = 0; i < priceChange.Length; i++)
            {
                int tempSum = 0;
                for (int j = i; j < priceChange.Length; j++)
                {
                    tempSum += priceChange[j];
                    if (tempSum > sum)
                    {
                        startIndex = i;
                        endIndex = j;
                        sum = tempSum;
                    }
                }
            }

            Console.WriteLine("最大收益为:{0},第{1}天买入,第{2}天卖出", sum, startIndex, endIndex + 1);
        }
    }
}

分治法

解题思路:将数组分成两份,最大子数组(元素之和最大)只有三种情况:
(1)最大子数组在mid左边,即:startIndex和endIndex都在mid左边
(2)最大子数组一半在左边,一半在右边,即:startIndex在 mid左边,endIndex在mid右边
(3)最大子数组在mid右边,即:startIndex和endIndex都在mid右边
那么比较三种情况下的最大子数组的结果接可以了,最终得出最大子数组
那么继续运用递归,继续给mid左边和右边进行分治求解,将复杂的问题进行简化,以此降低了代码的时间复杂度,提高了程序的运行效率。

代码实现:

using System;

namespace cchoop
{
    class Program
    {
        public static void Main()
        {
            int[] price = new int[] { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
            int[] priceChange = new int[price.Length - 1];
            for (int i = 1; i < price.Length; i++)
            {
                priceChange[i - 1] = price[i] - price[i - 1];
            }

            MaxProfit maxProfit = GetMaxProfit(priceChange, 0, priceChange.Length - 1);
            Console.WriteLine("最大收益为:{0},第{1}天买入,第{2}天卖出", maxProfit.ProfitNum, maxProfit.StartIndex, maxProfit.EndIndex + 1);
        }

        public static MaxProfit GetMaxProfit(int[] priceChange, int low, int high)
        {
            if (low == high)
            {
                MaxProfit maxProfit;
                maxProfit.StartIndex = low;
                maxProfit.EndIndex = high;
                maxProfit.ProfitNum = priceChange[low];
                return maxProfit;
            }

            int mid = (low + high) / 2;
            //startIndex、endIndex都在mid左边
            MaxProfit maxProfitLeft = GetMaxProfit(priceChange, low, mid);
            //startIndex、endIndex都在mid右边
            MaxProfit maxProfitRight = GetMaxProfit(priceChange, mid + 1, high);

            //startIndex在mid左边,endIndex在mid右边
            int startIndex = mid;
            int endIndex = mid;
            int totalProfit = priceChange[mid];
            int tempProfit = 0;
            //左边
            for (int i = mid; i >= 0; i--)
            {
                tempProfit += priceChange[i];
                if (tempProfit > totalProfit)
                {
                    totalProfit = tempProfit;
                    startIndex = i;
                }
            }
            //右边
            tempProfit = totalProfit;
            for (int i = mid + 1; i < priceChange.Length; i++)
            {
                tempProfit += priceChange[i];
                if (tempProfit > totalProfit)
                {
                    totalProfit = tempProfit;
                    endIndex = i;
                }
            }
            MaxProfit maxProfitMid;
            maxProfitMid.StartIndex = startIndex;
            maxProfitMid.EndIndex = endIndex;
            maxProfitMid.ProfitNum = totalProfit;

            //比较 三个maxProfit
            MaxProfit tempMaxProfit = maxProfitLeft;
            if (maxProfitMid.ProfitNum > tempMaxProfit.ProfitNum)
            {
                tempMaxProfit = maxProfitMid;
            }
            if (maxProfitRight.ProfitNum > tempMaxProfit.ProfitNum)
            {
                tempMaxProfit = maxProfitRight;
            }
            return tempMaxProfit;
        }
    }

    struct MaxProfit
    {
        public int StartIndex;
        public int EndIndex;
        public int ProfitNum;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_34937637/article/details/81282952