如何利用C++、C、Python求寻找最大的子阵列之和

143 阅读2分钟

问题

我们的目标是在一个连续的子数组中找到元素 nums 中的元素,这些元素具有给定数组的最高总和。

蛮力方法

天真的方法是产生所有可能的子阵列,然后显示总和最大的子阵列。

这将花费O(N2)的时间,效率很低。

高效的方法

目的是利用 Kadane算法 来发现最大的子阵列总和,记录总和最大的子阵列的起始和结束索引,然后打印从起始索引到结束索引的子阵列。具体步骤如下。

设置三个变量 end, curr,和 Max 为输入数组中的第一个值。

从索引(例如)0开始,将 curr 改为 max(``nums[i], nums[i] + Max``)Max,并将 结束设置 为 i 只有当 curr > Max.

为了得到起始索引,从 end 到左边,递减Max的值,直到它等于0 。起始索引是它变成零的那一点。

C++编程

#include <bits/stdc++.h>
using namespace std;
void maxSubarray(vector<int>& nums)
{
    // Initialize curr and Max
    int end, curr = nums[0];
    int Max = nums[0];

    // Iterate for all the elements for maximum sum
    for (int i = 1; i < nums.size(); ++i) 
    { 
         curr = max(nums[i], nums[i] + curr); 
         // Check if curr is greater 
         // than Max 
         if (curr > Max) 
        {
            Max = curr;
            end = i;
        }
    }

    int start = end;

    // Traverse in left direction
    while (start >= 0) {

        Max -= nums[start];

        if (Max == 0)
            break;

        // decrement the start index
        start--;
    }
    for (int i = start;
        i <= end; ++i) {

        cout << nums[i] << " ";
    }
}

int main()
{
    vector<int> nums
        = { 1, 2, 3, -4};
    maxSubarray(nums);
}

输出

1 2 3

Python编程

def maxSubarray(nums):
    
    # Initialize curr and Max
    curr = nums[0]
    Max = nums[0]

    # Iterate for all the elements
    for i in range(1, len(nums)):
        curr = max(nums[i], nums[i] + curr)

        # Check if curr is greater
        # than Max
        if (curr > Max):
            Max = curr
            end = i
    
    start = end

    # Traverse in left direction
    while (start >= 0):
        Max -= nums[start]

        if (Max == 0):
            break

        # Decrement the start index
        start -= 1
    for i in range(start, end + 1):
        print(nums[i], end = " ")
arr = [1, 2, 4, -5]
maxSubarray(arr)

输出

1 2 4

C#编程

using System;
using System.Collections.Generic;
class Solution{

static void maxSubarray(List<int> nums)
{
    // Initialize curr and Max
    int end = 0, curr = nums[0];
    int Max = nums[0];

    // Iterate for all the elements
    for (int i = 1; i < nums.Count; ++i) 
    { 
        curr = Math.Max(nums[i], nums[i] + curr); 
       // Check if curr is greater 
       // than Max 
       if (curr > Max)
       {
          Max = curr;
          end = i;
        }
    }

    int start = end;

    // Traverse in left direction
    while (start >= 0)
    {
    Max -= nums[start];

    if (Max == 0)
        break;

    // decrement the start index
    start--;
    }
    for(int i = start; i <= end; ++i)
    {
    Console.Write(nums[i] + " ");
    }
}

public static void Main(String[] args)
{
    List<int> nums = new List<int>();
    nums.Add(1);
    nums.Add(2);
    nums.Add(-1);
    nums.Add(3);
    maxSubarray(nums);
}
}

输出

1 2 -1 3