一、算法_分治算法

分治算法

  • 分治算法介绍
    • 二分搜索
    • 大整数乘法
    • 棋盘覆盖
    • 合并排序
    • 快速排序
    • 线性时间选择

  分治算法介绍:简单点理解就是分开处理,如果一个问题可以容易的解决,则直接解决,否则将其分解为规模较小的子问题去解决,子问题与原问题形式相同,递归子问题,然后将子问题的解合并。

如问题一如果卖出黄金,求黄金最大收益:

01234567891011121314
黄金价格506575656668685678807572707071
波动01510-10120-12222-5-3-201



    解决方法:(最大子数组)

  1. 暴力求解(吞吐量大)
  2. 分治法

一、暴力求解

  static void Main (string[] args) {
            //  黄金价格
            int[] pPriceArray = { 50, 65, 75, 65, 66, 68, 68, 56, 78, 80, 75, 72, 70, 70, 71 };
            //  波动的价格
            int[] pPriceWaveArray = new int[pPriceArray.Length - 1];
            for (int i = 1; i < pPriceArray.Length; i++) {
                pPriceWaveArray[i - 1] = pPriceArray[i] - pPriceArray[i - 1];
            }
            //  默认最大子数组是第一个元素
            int pMaxTatal = pPriceWaveArray[0];
            int pStartIndex = 0;
            int pEndIndex = 0;
            for (int i = 0; i < pPriceWaveArray.Length; i++) {
                //  取得所有子数组
                for (int j = i; j < pPriceWaveArray.Length; j++) {
                    int pTempMaxTotal = 0;
                    for (int k = 0; k < j + 1; k++) {
                        pTempMaxTotal += pPriceWaveArray[k];
                        if (pTempMaxTotal > pMaxTatal) {
                            pMaxTatal = pTempMaxTotal;
                            pStartIndex = i;
                            pEndIndex = j;
                        }
                    }
                }
            }
            Console.WriteLine("Start Index: " + pStartIndex);
            Console.WriteLine("End Index: " + (pEndIndex + 1));
            Console.WriteLine("buy day: " + pStartIndex + "Sell Day: " + (pEndIndex + 1));
            Console.ReadKey();

  }

二、分治法

// 子数组
    struct MaxArray {
        public int pStartIndex;
        public int pEndIndex;
        public int pSubTotal;
    }

    static void Main (string[] args) {

        //  黄金价格
        int[] pPriceArray = { 50, 65, 75, 65, 66, 68, 68, 56, 78, 80, 75, 72, 70, 70, 71 };
        //  波动的价格
        int[] pPriceWaveArray = new int[pPriceArray.Length - 1];
        for (int i = 1; i < pPriceArray.Length; i++) {
            pPriceWaveArray[i - 1] = pPriceArray[i] - pPriceArray[i - 1];
        }
        MaxArray pMaxArray = GetMaxArray(0, pPriceWaveArray.Length - 1, pPriceWaveArray);

        Console.WriteLine("Buy Day: " + pMaxArray.pStartIndex);
        Console.WriteLine("Sell Day: " + (pMaxArray.pEndIndex + 1));
        Console.ReadKey();

    }
    //  取数组中从low到high中的子数组
    static MaxArray GetMaxArray (int low, int high, int[] array) {
        if (low == high) {
            MaxArray pMaxArray;
            pMaxArray.pStartIndex = low;
            pMaxArray.pEndIndex = high;
            pMaxArray.pSubTotal = array[low];
            return pMaxArray;
        }
        //  low区间[low,mid] 高区间[mid+1,high]
        int pMidIndex = (low + high) / 2;
        MaxArray pMaxArray1 = GetMaxArray(low, pMidIndex, array);
        MaxArray pMaxArray2 = GetMaxArray(pMidIndex + 1, high, array);

        // 从[low,mid]找最大子数组[i , mid]
        int pSubTotalLow = array[pMidIndex];
        int pStartIndex = pMidIndex;
        int pSubTempTotal = 0;
        for (int i = pMidIndex; i >= low; i--) {
            pSubTempTotal += array[i];
            if (pSubTempTotal > pSubTotalLow) {
                pSubTotalLow = pSubTempTotal;
                pStartIndex = i;
            }
        }

        // 从 [mid+1,high]找到最大子数组[mid+1,j]
        int pSubTotalHigh = array[pMidIndex + 1];
        int pEndIndex = pMidIndex + 1;
        pSubTempTotal = 0;
        for (int j = pMidIndex + 1; j <= high; j++) {
            pSubTempTotal += array[j];
            if (pSubTempTotal > pSubTotalHigh) {
                pSubTotalHigh = pSubTempTotal;
                pEndIndex = j;
            }
        }
        MaxArray pMaxArray3;
        pMaxArray3.pStartIndex = pStartIndex;
        pMaxArray3.pEndIndex = pEndIndex;
        pMaxArray3.pSubTotal = pSubTotalLow + pSubTotalHigh;
        if (pMaxArray1.pSubTotal >= pMaxArray2.pSubTotal && pMaxArray1.pSubTotal >= pMaxArray3.pSubTotal) {
            return pMaxArray1;
        } else if (pMaxArray2.pSubTotal >= pMaxArray1.pSubTotal && pMaxArray2.pSubTotal >= pMaxArray3.pSubTotal) {
            return pMaxArray1;
        } else {
            return pMaxArray3;
        }
    }

大概图解

这里写图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值