连续项的最大和问题
(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);
}