最大子数组问题

求一组数字里面最大的子数组的和

在这里插入图片描述

第一种暴力解决

在这里插入图片描述但是发现很多重复计算的值可以省略的。

下面是优化
在这里插入图片描述

用分而治之的算法

在这里插入图片描述
在这里插入图片描述

对于跨越的数组
在这里插入图片描述
这里求解最大值
找左边最大的子数组
找右边最大的子数组
相加就是最大子数组

在这里插入图片描述

在这里插入图片描述

治与合

在这里插入图片描述
整体思路:就是从分到治到合的过程
在这里插入图片描述

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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值