算法-连续项的最大和问题(最大子数组问题)三种不同解法

连续项的最大和问题

(1)暴力求解 时间复杂度 O(n^2)
(2)分治求解 时间复杂度 O(nlogn)
(3) 线性求解 时间复杂度 O(n)

C#代码

using System;
using System.Collections.Generic;

namespace dataLearn
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> list1 = new List<int> { -2, 4, -1, 3, 5, -6, 1, 2 };
            List<int> list2 = new List<int> { 4, 1, -3, 7, -1, -5, 3, -2 };
            List<int> list3 = new List<int> { -1, 6, 3, -4, -5, 8, -1, 7 };
            var max1 = MaxSumViolence(list1, 0, list1.Count - 1);
            Console.WriteLine(max1.start + " " + max1.end + " " + max1.value);
            var max2 = MaxSumViolence(list2, 0, list2.Count - 1);
            Console.WriteLine(max2.start + " " + max2.end + " " + max2.value);
            var max3 = MaxSumViolence(list3, 0, list3.Count - 1);
            Console.WriteLine(max3.start + " " + max3.end + " " + max3.value);
            var max4 = MaxSum(list1, 0, list1.Count - 1);
            Console.WriteLine(max4.start + " " + max4.end + " " + max4.value);
            var max5 = MaxSum(list2, 0, list2.Count - 1);
            Console.WriteLine(max5.start + " " + max5.end + " " + max5.value);
            var max6 = MaxSum(list3, 0, list3.Count - 1);
            Console.WriteLine(max6.start + " " + max6.end + " " + max6.value);
        }
        
        static (int start,int end,float value) MaxSumViolence(List<int> list ,int start,int end)
        {
            int s = start, e = end;
            int max = list[start];
            for(int i=start;i<end+1;i++)
            {
                int total = list[i];
                for(int j=i+1;j<end+1;j++)
                {
                    total += list[j];
                    if(total>max)
                    {
                        max = total;
                        s = i;
                        e = j;
                    }
                }
            }
            return (s, e, max);
        }
        static (int start,int end,float value) MaxSum(List<int> list,int start,int end)
        {
            if (start != end)
            {
                int middle = (start + end) / 2;
                var leftMax = MaxSum(list, start, middle);
                var rightMax = MaxSum(list, middle + 1, end);
                var max = leftMax.value > rightMax.value ? leftMax : rightMax;
                int l = middle, r = middle + 1;
                float lvalue = list[middle];
                float rvalue = list[middle + 1];
                float temp = lvalue;
                for (int i = middle - 1; i >= start; i--)
                {
                    temp += list[i];
                    if (temp > lvalue)
                    {
                        l = i;
                        lvalue = temp;
                    }
                }
                temp = rvalue;
                for (int i = middle + 2; i <= end; i++)
                {
                    temp += list[i];
                    if (temp > rvalue)
                    {
                        r = end;
                        rvalue = temp;
                    }
                }
                if (max.value < lvalue + rvalue)
                {
                    return (l, r, lvalue + rvalue);
                }
                else return max;
            }
            else
                return (start, start, list[start]);
        }
    }
}

c++ 代码
数据结构

#include <iostream>
class SubarrayResult{
public:
    int value;
    int left;
    int right;
public:
    SubarrayResult(int value,int left,int right):value(value),left(left),right(right){};
    SubarrayResult(){};
    friend std::ostream & operator<<(std::ostream &os,const SubarrayResult &result)
    {
        return os<<"value:"<<result.value<<",left:"<<result.left<<",right:"<<result.right;
    }
    bool operator>=(const SubarrayResult & other)
    {
        return this->value>= other.value;
    }
};

暴力求解法:时间复杂的O(n^2)

SubarrayResult brute_force_find_maximum_subarray(int *arr,int start,int end)
{
    int max_sum = INT_MIN;
    int sum = 0;
    int low = 0;
    int high = 0;
    for (int i = start; i < end+1; ++i) {
        sum = 0;
        for (int j = i; j < end+1 ; ++j) {
            sum += arr[j];
            if(sum>max_sum)
            {
                max_sum = sum;
                low = i;
                high = j;
            }
        }
    }
    return SubarrayResult(max_sum,low,high);
}

分治递归求解法:
T(n)=2T(n/2)+θ(n)
时间复杂度(nlgn)

SubarrayResult find_crossing_subarray(int *arr,int start,int end ,int middle);

SubarrayResult find_maximum_subarray(int *arr,int start,int end)
{
    if(start == end)
        return SubarrayResult(arr[start],start,end);
    else
    {
        int middle = (start + end)/2;
        SubarrayResult left_result = find_maximum_subarray(arr,start,middle);
        SubarrayResult right_result = find_maximum_subarray(arr,middle+1,end);
        SubarrayResult cross_result = find_crossing_subarray(arr,start,end,middle);

        if(left_result >= right_result && left_result >= cross_result)
            return left_result;
        else if(right_result >= left_result && right_result >= cross_result)
            return right_result;
        else return cross_result;
    }
}

SubarrayResult find_crossing_subarray(int *arr,int start,int end, int middle)
{
    int left_sum = INT_MIN,right_sum = INT_MIN;
    int sum = 0,max_left = 0, max_right = 0;
    for (int i = middle; i >= start ; i--) {
        sum += arr[i];
        if(sum>left_sum){
            left_sum = sum;
            max_left = i;
        }
    }
    sum = 0;
    for (int i = middle + 1; i < end+1; ++i) {
        sum += arr[i];
        if(sum>right_sum)
        {
            right_sum = sum;
            max_right = i;
        }
    }
    return SubarrayResult(left_sum+right_sum,max_left,max_right);
}

线性求解法:
时间复杂度O(n)

SubarrayResult iterative_find_maximum_subarray(int *arr,int start,int end)
{
    int left = 0,right = 0,current_low = 0,current_high = 0;
    int sum = INT_MIN ,max_sum = INT_MIN;
    for (int i = start; i < end+1; ++i) {
        current_high = i;
        if(sum > 0)
        {
            sum += arr[i];
        }
        else
        {
            current_low = i;
            sum = arr[i];
        }
        if(sum > max_sum)
        {
            max_sum = sum;
            left = current_low;
            right = current_high;
        }
    }
    return SubarrayResult(max_sum,left,right);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值