最大子数组问题/Maximum Subarray

问题描述:

Find the contiguous subarray within an array (containing at least one number) which has the largest sum. 
For example, given the array [−2,1,−3,4,−1,2,1,−5,4], 
the contiguous subarray [4,−1,2,1] has the largest sum = 6.

问题分析(参考了算法导论第4章分治策略的内容):

为求一个含负数的一组数种,和为最大的子数组
这里使用分治的思想

首先,这一个子数组它只可能以3种方式存在:
完全在上半部分:low--mid
完全在下半部分:mid--high
或者跨越中点地存在:可理解为Arr[i..mid]+[mid+1..j]最大的元素和组成

 算法的思想:递归地寻求左、右部分的最大子数组和
最后合并每次递归结果的解(只保留最后最大的结果)

时间复杂度分析:

n=1 T(1)=Θ(1)
n>1 子问题——求解左子数组和右子数组;每组子问题求解花费T(n/2)
所以算法的运行时间T(n)递归式为:
T(n)= Θ(1)       ,n=1
              2T(n/2)  ,n>1
最后可以求解出T(n)=Θ(nlgn)

 1 #include<iostream>
 2 #include<climits>
 3 using namespace std;
 4 const int infinite=-9999;
 5 int Find_Max_Crossing_Subarray(int arr[],int low,int mid,int high)//扫描上半部分最大和、下半部分最大和,上下部分结合为跨越中点最大和
 6 {
 7 
 8     int left_sum=infinite;
 9     int right_sum=infinite;
10     int max_left=-1,max_right=-1,sum=0;
11     for(int i=mid; i>=low; i--)
12     {
13         sum+=arr[i];
14         if(sum>left_sum)
15         {
16             left_sum=sum;
17             max_left=i;
18         }
19     }
20     sum=0;
21     for(int j=mid+1; j<=high; j++)
22     {
23         sum+=arr[j];
24         if(sum>right_sum)
25         {
26             right_sum=sum;
27             max_right=j;
28         }
29     }
30     return (left_sum+right_sum);
31 }
32 int Find_Maximum_Subarray(int arr[],int low,int high)//
33 {
34     if(high==low)//只有一个元素的时候
35         return arr[low];
36     else
37     {
38         int mid=(low+high)/2;
39         int leftSum=Find_Maximum_Subarray(arr,low,mid);
40         int rightSum=Find_Maximum_Subarray(arr,mid+1,high);
41         int crossSum=Find_Max_Crossing_Subarray(arr,low,mid,high);
42         if(leftSum>=rightSum&&leftSum>=crossSum)
43             return leftSum;
44         else if(rightSum>=leftSum&&rightSum>=crossSum)
45             return rightSum;
46         else return crossSum;
47     }
48 }
49 int main()
50 {
51     int arr[10]= {5,2,8,-6,9,1,10,7,-13,9};
52     int ans=Find_Maximum_Subarray(arr,0,9);
53     cout<<ans<<endl;
54     return 0;
55 }

 

转载于:https://www.cnblogs.com/AKsnoopy/p/8535347.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值