今天我们一起来看一下关于最大子数组的一些问题。最大子数组的应用场景可以是这样的:有一天,你搞了一场投资开始炒股,这时你就会想,我怎样才能获得最大的利润呢,最简单的想法就是我在股票的最低价时买入,然后在最高价时卖出,这样利润必然最大。但冷静下来想想这往往是不可能的,你不能保证最高价出现在最低价后面。为了达到这一目的,我们建立了最大子数组模型。我们以一年为时间期限,每个月的股价假设是这样的13 12 15 18 19 18 20 16 13 9 11 10,为了获得最大利益,我们要寻找差值最大的两个数(后一个减前一个)。为了简化模型,我们从另外一个角度来看待这个问题。当我们从数据的变化(也就是从后一个月相对于前一个月价格的变化量)角度来看待这个问题时,这一串数字就变成了这个样子0 -1 3 3 1 -1 2 -4 -3 -4 2 -1,这样问题就转化为寻找这个数组的最大非空连续子数组问题了。 下面我们就来讨论一下这个问题的解法:

 

解法一:暴力求解

  最简单最直接的想法就是我求出所有非空连续子数组的和,再通过比较找到最大的一个子数组不就行了吗。确实可以,通过for循环遍历我们可以得到这样的伪代码:

暴力求解伪代码:

FindMaxSubarray(A,low,high)

1. maxSum = 负无穷大

2. sum = 0

3. for i = 1 to n

4.  for j = i to n

5.     sum=sum+A[j]

6.     if sum > maxSum

7.      maxSum = sum

8.      maxLeft = i

9.      maxRight = j

10.  sum = 0

11. return (maxLeft,maxRight,maxSum)

 

伪代码讲解:

第一二行,maxSum用来表示当前扫描过的最大子数组的和,sum用来表示当前子数组的和

第三到十行,主体扫描所有子数组并求和,记录最大子数组的起始位置i、结束位置j以及和sum

第十一行返回扫描结果

 

C语言完整代码:

/*Author: Terry Zhang*/
#include <stdio.h>
#include <stdlib.h>

struct info{
    int maxLeft;
    int maxRight;
    int Sum;
};
int main()
{
    size_t n;
    scanf_s("%d", &n);
    int *p = (int *)calloc(n, sizeof(int));
    for (size_t i = 0; i < n; i++)
    {
        scanf_s("%d", p + i);
    }

    info Find_Max_Subarray(int A[], int low, int high);
    info inf;
    inf = Find_Max_Subarray(p, 0, n - 1);

    //输出结果
    printf("MaxLeft:%d\n", inf.maxLeft+1);      //默认起始位置为1
    printf("MaxRight:%d\n", inf.maxRight+1);
    printf("MaxSum:%d\n", inf.Sum);

    if (p != NULL)
        free(p);
    return 0;
}

info Find_Max_Subarray(int A[], int low, int high)
{
    int maxSum = INT_MIN;
    int maxLeft = 0;
    int maxRight = 0;
    int sum = 0;
    for (size_t i = low; i <= high; i++)
    {
        for (size_t j = i; j < high; j++)
        {
            sum += A[j];
            if (sum >= maxSum)
            {
                maxSum = sum;
                maxLeft = i;
                maxRight = j;
            }
        }
        sum = 0;
    }

    info inf;
    inf.maxLeft = maxLeft;
    inf.maxRight = maxRight;
    inf.Sum = sum;

    return inf;
}
View Code

相关文章:

  • 2022-01-29
  • 2018-03-14
  • 2021-12-29
  • 2022-12-23
  • 2022-01-26
  • 2021-08-20
  • 2021-11-05
  • 2021-12-15
猜你喜欢
  • 2018-09-01
  • 2021-12-18
  • 2021-10-22
  • 2022-12-23
  • 2022-01-21
相关资源
相似解决方案