【Leetcode】53. Maximum Subarray
来源:互联网 发布:网红美妆淘宝店前十名 编辑:程序博客网 时间:2024/05/29 08:45
Description:
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
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.
思路:
此题有多种解题思路。常规的解题方式,可以通过循环逐个比较连续的子数组(或者叫子序列)内元素的和的大小,以下是C++的实现方式
class Solution{ public: int MaxSubArray(int *arr,int len,int left, int right){ int temp = 0; int max = 0; for(i=0;i<len;i++){ temp = 0; for(j=i;j<len;j++){ temp += arr[j]; if(temp>max){ max = temp; left = i; right = j; } } } return max; } private: int i,j,len; int *arr; int left,right;//数组的左右两端起末位置};
但是这种方法的时间复杂度为O(n^2),对于数组元素个数较多的时候,效率会比较低。
我们可以仔细观察得到,循环比较逐个比较把所有可能的子序列都计算了一遍,但实际上不需要计算所有的子序列,如果有些子序列的开头和结尾是负数的话是无法得到和的最大值,因此可以只计算开头和结尾为正数的。更具体来说,开头是正数可以转换为这样一个问题:上一个元素的值a[i-1]与当前元素的值a[i]的和比当前元素的值a[i]要小,那么取当前元素的位置作为最大子序列的起始位置,否则保持不变。同样的,结尾为正数可以转化为:当前元素的值a[i]和下一个元素的值a[i+1]比当前元素大,那么下一个元素的位置作为最大子序列的结束位置,否则保持不变。这样,我们得到了一个递归的解决方式。
class Solution { public: int MaxSubArray(int *arr,int len){ int max_sum = arr[0]; int max_end_pos = arr[0]; int sum = 0; left = 0; right = 0; for(int i=1;i<len;i++){ sum = max_end_pos + arr[i]; if(sum > arr[i]){ max_end_pos = sum; }else{ max_end_pos = arr[i]; left = i; } if(max_sum<max_end_pos){ max_sum = max_end_pos; right = i; } } return max_sum; } private: int i,j,len; int *arr; int left,right;};
由此可见,该算法中只有一次循环,算法复杂度为O(n),拥有十分优异的效率。
除此之外,该问题还可以用分治法来解答。用分治法的时间复杂度为O(nlogn),比常规算法效率高。
class Solution{ public: int MaxInThree(int a,int b,int c){ if(a>b) a = b; if(a<c) return c; else return a; } int MaxSubArray(int *arr,int left,int right){ int max_left_sum,max_right_sum;//左右两半部分最大的和 int sub_left_sum=0,sub_right_sum=0; //左子序列的和与右子序列的和 int max_sub_left_sum=0,max_sub_right_sum=0;//左子序列的最大和与右子序列的最大和 int mid; //当只有一个元素的时候 if(left==right){ if(a[left]>0) return a[left] else return 0; } //将数组分为两部分,分别求两部分的和的最大值 mid=(left+right)/2; max_left_sum = MaxSubArray(arr,left,mid); max_right_sum = MaxSubArray(arr,mid+1,right); //在左半部分从中间到左侧进行子序列匹配 for(i=mid;i>=left;i--){ sub_left_sum+=arr[i]; if(sub_left_sum>max_sub_left_sum) max_sub_left_sum = sub_left_sum; } //在右半部分从中间到右侧进行子序列匹配 for(i=mid+1;i<=right;i++){ sub_right_sum+=arr[i]; if(sub_right_sum>max_sub_right_sum) max_sub_right_sum = sub_right_sum; } return MaxInThree(max_left_sum,max_right_sum,max_sub_left_sum+max_sub_right_sum); } private: int i,j,len; int *arr; int left,right;};
0 0
- [LeetCode]53.Maximum Subarray
- LeetCode --- 53. Maximum Subarray
- [Leetcode] 53. Maximum Subarray
- [leetcode] 53.Maximum Subarray
- 【leetcode】53. Maximum Subarray
- [leetcode] 53.Maximum Subarray
- 【leetcode】53. Maximum Subarray
- LeetCode 53. Maximum Subarray
- [LeetCode]53. Maximum Subarray
- 53. Maximum Subarray LeetCode
- [LeetCode]53. Maximum Subarray
- leetcode 53. Maximum Subarray
- [leetcode] 53. Maximum Subarray
- LeetCode *** 53. Maximum Subarray
- 【LeetCode】53. Maximum Subarray
- leetcode 53. Maximum Subarray
- LeetCode 53. Maximum Subarray
- Leetcode:53. Maximum Subarray
- MapReduce WordCount
- Redis客户端命令总结
- (6)spring boot下使用jdbcTemplate操作数据库
- java中四种操作(dom、sax、jdom、dom4j)xml方式详解与比较
- 添加xxx库混淆配置
- 【Leetcode】53. Maximum Subarray
- OkMap.v13.4.1.Win64 1CD
- 解决问题:Initializing test library 'AutoItLibrary' with no arguments failed: com_error: (-2147221164, '\
- sdutacm-顺序表应用3:元素位置互换之移位算法
- Windows第一次实验(3)
- Java NIO 详解(一)
- C#连接Excel提示“外部表不是预期的格式”
- 希尔排序
- 删除