【Leetcode】53. Maximum Subarray
2017-03-03 16:16
459 查看
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; };
相关文章推荐
- LeetCode:53. Maximum Subarray
- leetcode 53. Maximum Subarray
- Leetcode题解 - 53. Maximum Subarray
- leetcode_53. Maximum Subarray-子数组最大和
- [Leetcode]53. Maximum Subarray
- 【算法作业10】LeetCode 53. Maximum Subarray
- [LeetCode By Python]53. Maximum Subarray
- Leetcode题解 53. Maximum Subarray 思路解析
- LeetCode53. Maximum Subarray一种很好的做法
- Leetcode解题笔记 53. Maximum Subarray [Easy] 动态规划
- [LeetCode] 53. Maximum Subarray
- Leetcode 53. Maximum Subarray
- 【leetcode】53. Maximum Subarray
- [LeetCode]53. Maximum Subarray
- 【C++】【LeetCode】53. Maximum Subarray
- [leetcode] 53. Maximum Subarray
- leetcode题解-53. Maximum Subarray && 448. Find All Numbers Disappeared in an Array
- 小白笔记-----------------------------leetcode53. Maximum Subarray
- LeetCode 53. Maximum Subarray
- Leetcode 53. Maximum Subarray