一、算法_分治算法

分治算法

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

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

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

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
黄金价格 50 65 75 65 66 68 68 56 78 80 75 72 70 70 71
波动 0 15 10 -10 1 2 0 -12 22 2 -5 -3 -2 0 1



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

  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张图片

你可能感兴趣的:(C#高级,算法)