Leetcode题集——maximum-subarray
来源:互联网 发布:林心如律师发声明知乎 编辑:程序博客网 时间:2024/05/29 02:51
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.
click to show more practice.
解析:求一个输入数组的连续子序列的最大和值。
方法一:动态规划法:
时间复杂度为O(n)。
设sum[i]为以第i个元素结尾且和最大的连续子数组。假设对于元素i,所有以它前面的元素结尾的子数组的长度都已经求得,那么以第i个元素结尾且和最大的连续子数组实际上,要么是以第i-1个元素结尾且和最大的连续子数组加上这个元素,要么是只包含第i个元素,即sum[i] = max(sum[i-1] + a[i], a[i])。可以通过判断sum[i-1] + a[i]是否大于a[i]来做选择,而这实际上等价于判断sum[i-1]是否大于0。由于每次运算只需要前一次的结果,因此并不需要像普通的动态规划那样保留之前所有的计算结果,只需要保留上一次的即可,因此算法的时间和空间复杂度都很小。
class Solution {public: bool invalidinput=false; int maxSubArray(int A[], int n) { if(A==NULL||n<=0) { invalidinput=true; return 0; } invalidinput=false; int cursum=0; int sum=0x80000000; for(int i=0;i<n;i++) { if(cursum<=0) cursum=A[i]; else cursum+=A[i]; if(cursum>sum) sum=cursum; } return sum; }};方法二、分治方法
也就是递归求解。时间复杂度为O(nlogn)。这是个分治的思想,解决复杂问题我们经常使用的一种思维方法——分而治之。
而对于此题,我们把数组A[1..n]分成两个相等大小的块:A[1..n/2]和A[n/2+1..n],最大的子数组只可能出现在三种情况:
A[1..n]的最大子数组和A[1..n/2]最大子数组相同;
A[1..n]的最大子数组和A[n/2+1..n]最大子数组相同;
A[1..n]的最大子数组跨过A[1..n/2]和A[n/2+1..n]
前两种情况的求法和整体的求法是一样的,因此递归求得。
第三种,我们可以采取的方法也比较简单,沿着第n/2向左搜索,直到左边界,找到最大的和maxleft,以及沿着第n/2+1向右搜索找到最大和maxright,那么总的最大和就是maxleft+maxright。因为要跨过中间点,因此返回必须为maxleft和maxright之和!
而数组A的最大子数组和就是这三种情况中最大的一个。
int find_max_crossing(int arr[],int low,int mid,int high,int *left,int *right){ int lsum=-100; int sum=0; for(int i=mid;i>=low;--i) { sum+=arr[i];if(sum>lsum){ lsum=sum; *left=i;} } int rsum=-100; sum=0; for(int j=mid+1;j<=high;j++) { sum+=arr[j];if(sum>rsum){ rsum=sum; *right=j;} } return rsum+lsum;}int max_sum_array(int arr[],int low,int high,int *left,int *right){ if(low==high) {//递归结束点 *left=low; *right=high; return arr[low]; } int mid=(low+high)/2; int lleft,lright,rleft,rright,mleft,mright; //三种情况下分别求解 int lmax=max_sum_array(arr,low,mid,&lleft,&lright); int rmax=max_sum_array(arr,mid+1,high,&rleft,&rright); int mmax=find_max_crossing(arr,low,mid,high,&mleft,&mright); //返回最大值 if(lmax>rmax&&lmax>mmax) { *left=lleft; *right=lright; return lmax; } if(rmax>lmax&&rmax>mmax) { *left=rleft; *right=rright; return rmax; } if(mmax>lmax&&mmax>rmax) { *left=mleft; *right=mright; return mmax; } }
- Leetcode题集——maximum-subarray
- LeetCode——Maximum Subarray
- LeetCode——Maximum Subarray
- leetcode——Maximum Subarray
- LeetCode——Maximum Subarray
- LeetCode——Maximum subarray
- LeetCode—Maximum Product Subarray
- LeetCode——Maximum Product Subarray
- LeetCode——Maximum Product Subarray
- leetcode 053 —— Maximum Subarray
- leetcode 152 —— Maximum Product Subarray
- Maximum Product Subarray —— Leetcode
- leetcode——Maximum Product Subarray
- leetcode题解——53. Maximum Subarray
- Leetcode——53. Maximum Subarray
- LeetCode——152. Maximum Product Subarray
- 数据结构与算法[LeetCode]—Maximum Subarray
- leetcode——53——Maximum Subarray
- Arcengine 计算两个面之间的距离
- Hive本地模式安装配置
- 管道模式
- 2.IntelliJ IDEA 配置Tomcat
- python实现端口扫描
- Leetcode题集——maximum-subarray
- LeanCloud Demos分类汇总
- ob缓冲实例
- 如何通过JQ,Ajax来实现返回到上一个页面并进行刷新
- ListView 优化总结
- Android 事件分发机制(最新源码6.0分析)--ViewGrop
- POJ 2388 排序
- 动画加载ListView
- css选择器与jquery选择器