zoukankan      html  css  js  c++  java
  • 分治算法-最大子数组问题

    1.蛮力法求解

    总体思路:

      蛮力法是最简单的实现方法,只要列出数组所有可能的组合,然后找出其中和最大的组合即可;

      蛮力法分三层循环实现:

        1)第一层循环用于固定子数组的起始位置;

        2)第二层循环用于确定子数组的结束位置;

        3)第三层循环用于子数组和的计算,从子数组的头开始遍历到其尾,累加起来就是该子数组的和。

    实现:

       /// <summary>
            /// 暴力求解
            /// </summary>
            /// <param name="priceArray"></param>
            /// <param name="priceFlutuationsArray"></param>
            public static void Violentsolution(int[] priceArray,int[] priceFlutuationsArray)
            {
                int total = priceFlutuationsArray[0];//默认数组得第一个元素 是最大子数组
                int StartIndex = 0;
                int EndIndex = 0;
    
                for (int i = 0; i < priceFlutuationsArray.Length; i++)
                {
                    //取得以i为子数组起点得 所有子数组
                    for (int j = i; j < priceFlutuationsArray.Length; j++)
                    {
                        //由i j就确定了一个子数组
                        int totalTemp = 0;//临时最大子数组得和
                        for (int k = i; k < j + 1; k++)
                        {
                            totalTemp += priceFlutuationsArray[k];
                        }
                        if (totalTemp > total)
                        {
                            total = totalTemp;
                            StartIndex = i;
                            EndIndex = j;
                        }
                    }
                }
                Console.WriteLine("start:" + StartIndex);
                Console.WriteLine("End:" + EndIndex);
                Console.WriteLine("购买日期是第" + StartIndex + "天 出售日期是第" + (EndIndex + 1) + "");
                Console.WriteLine("total:" + total);
            
              }

    2.分治法求解

    总体思路:

      分治法的精髓:
        1)分--将问题分解为规模更小的子问题;
        2)治--将这些规模更小的子问题逐个击破;
        3)合--将已解决的子问题合并,最终得出“母”问题的解;
      所以原数组的最大子数组求法:
        1)分--将原数组拆分成两部分,每个部分再拆分成新的两部分......直到数组被分得只剩下一个元素;
        2)治--每个小型的数组找最大子数组,只有一个元素的数组,解就是该元素;
        3)合--将两个小型数组合并为一个数组,其中解有三种可能:
        • 左边的返回值大,
        • 右边的返回值大,
        • 中间存在一个更大的子数组和;
         返回值应选最大的;

    实现:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace 最大子数组问题
    {
        class Program
        {
            //最大子数组的结构体
            struct SubArray
            {
                public int startIndex;
                public int endIndex;
                public int total;
            }
            static void Main(string[] args)
            {
                int[] priceArray = { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
                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(subArray.startIndex);
                Console.WriteLine(subArray.endIndex);
                Console.WriteLine("我们在第" + subArray.startIndex + "天买入, 在第" + (subArray.endIndex + 1) + "天卖出");
                Console.ReadKey();
            }
    
            /// <summary>
            /// 这个方法用来取得array这个数组从low到high得最大子数组
            /// </summary>
            /// <param name="low"></param>
            /// <param name="high"></param>
            /// <param name="array"></param>
             static SubArray GetMaxSubArray(int low,int high,int[] array)
            {
                if (low == high)
                {
                    SubArray subarray;
                    subarray.startIndex = low;
                    subarray.endIndex = high;
                    subarray.total = array[low];
                    return  subarray;
                }
    
                int mid = (low + high)/2; //低区间[low,mid]  高区间[mid+1,high]
    
                SubArray subArray1= GetMaxSubArray(low, mid, array);
    
                SubArray subArray2=GetMaxSubArray(mid+1, high, array);
    
                SubArray subArray3 = GetMaxSub(low, mid, high, array);
    
                if (subArray1.total >= subArray2.total && subArray1.total >= subArray3.total)
                {
                    return subArray1;
                }
                else if (subArray2.total >= subArray1.total && subArray2.total >= subArray3.total)
                {
                    return subArray2;
                }
                else
                {
                    return subArray3;
                }
            }
    
            static SubArray GetMaxSub(int low,int mid,int high,int[] array)
            {
                //从【low,mid】找到最大子数组[i,mid]
                int total1 = array[mid];
                int startIndex = mid;
                int totalTemp = 0;
                for (int i = mid; i >= low; i--)
                {
                    totalTemp += array[i];
                    if (totalTemp > total1)
                    {
                        total1 = totalTemp;
                        startIndex = i;
                    }
                }
    
                //从【mid+1,high】找到最大子数组[mid+1,j]
                int total2 = array[mid + 1];
                int endIndex = mid + 1;
                totalTemp = 0;
                for (int j = mid + 1; j <= high; j++)
                {
                    totalTemp += array[j];
                    if (totalTemp > total2)
                    {
                        total2 = totalTemp;
                        endIndex = j;
                    }
                }
                SubArray subArray3;
                subArray3.startIndex = startIndex;
                subArray3.endIndex = endIndex;
                subArray3.total = total1 + total2;
                return subArray3;
            }
        }
    }
  • 相关阅读:
    Intent
    What should we do next in general after collecting relevant data
    NOTE FOR Secure Friend Discovery in Mobile Social Networks
    missing pcap.h
    after building Android Source code
    plot point(one column)
    When talking to someone else, don't infer that is has been talked with others at first. It may bring repulsion to the person who is talking with you.
    进程基本知识
    Python input和raw_input的区别
    强制 code review:reviewboard+svn 的方案
  • 原文地址:https://www.cnblogs.com/rongweijun/p/8177354.html
Copyright © 2011-2022 走看看