leetcode题解——53. Maximum Subarray
2016-11-11 18:42
375 查看
题目的意思就是:在给定的数组中选取一组连续的子数组,使得这个子数组的和是所有子数组和最大值。
解法一(分治策略)
思路:我首先想到的是算法导论分治策略一章给出的解法: 假设我们要寻找数组A[left,right]中的最大子数组,分治策略要求我们把问题分解两个规模相当的子数组,也就是说要找的子数组的中心middle,然后考虑求解两个子数组A1[left,middle],A2[middle+1,right]。求出的子数组肯定出自下面三种情景:
子数组完全位于middle左侧
子数组完全位于middle右侧
子数组跨越了middle
第三种情况下,子数组最好求,只需要在middle左侧开始找到连续和最大子数组L,在middle右侧开始找到连续和最大子数组R,两个数组合并就可以得到跨越middle最大的子数组。
代码
str_array 结构体是用来存储最大子数组的区间和最大值;
find_Max_Crossing_Array()函数:因为寻找数组必须从middle开始,所以两个for循环均从middle开始,分别向左右查找。找到最大数组就更新索引和最大和,直到到达数组的两边。
typedef struct arra{ int left_; int right_; int sum_; }str_array; str_array find_Max_Crossing_Array(int *a, int left, int middle, int right) { int left_sum_max = INT_MIN; int right_sum_max = INT_MIN; int max_left = 0; int max_right = 0; int sum = 0; str_array tmp; for (int i = middle; i >= left; i--) { sum += *(a + i); if (sum >= left_sum_max) { left_sum_max = sum; max_left = i; } } sum = 0; for (int i = middle+1; i <= right; i++) { sum += *(a + i); if (sum >= right_sum_max) { right_sum_max = sum; max_right = i; } } tmp.left_ = max_left; tmp.right_ = max_right; tmp.sum_ = left_sum_max + right_sum_max; return tmp; }
算法复杂度,两个for循环都是遍历了整个数组,所以复杂度为O(n),线性时间复杂度。
有了上述代码,最可以设计最大子数组的代码了:
代码分析:如果数组只含有一个元素,直接返回;
如果数组只含有一个元素,直接返回
将数组分解,分别求解三种情况下的最大数组,各数组信息用left_array, right_array, acrossing_array保存
通过比较left_array.sum_,right_array.sum_,acrossing_array.sum_,选出这三个数组中和最大的数组
str_array find_Max_Sum_Child_Array(int *a, int left, int right) { str_array tmp; if (left == right) { tmp.left_ = left; tmp.right_ = right; tmp.sum_ = *(a + left); return tmp; } else { int middle = (left + right) / 2; str_array left_array, right_array, acrossing_array; left_array = find_Max_Sum_Child_Array(a, left, middle); right_array = find_Max_Sum_Child_Array(a, middle + 1, right); acrossing_array = find_Max_Crossing_Array(a, left, middle, right); if (left_array.sum_ >= right_array.sum_ && left_array.sum_ >= acrossing_array.sum_) return left_array; else if (right_array.sum_ >= left_array.sum_ && right_array.sum_ >= acrossing_array.sum_) return right_array; else return acrossing_array; } }
算法复杂度:递归结果调用了递归树,树的高度h=lgn,
复杂度T(n)=n*lgn;
下面是主函数,可以方便的获取最大子数组索引和sum:
int main() { int a[9] = { -2,1,-3,4,-1,2,1,-5,4 }; str_array result = find_Max_Sum_Child_Array(a, 0, 8); cout << result.left_ << " " << result.right_ << " " << result.sum_ << endl; system("pause"); return 0; }
运行结果:
问题差不多,所以在提交的时候基本上就是原来思路:
class Solution { int divide(vector<int>& nums,int l,int r){ if(l==r) return nums[l]; int m=(l+r)/2; int left=divide(nums,l,m); int right=divide(nums,m+1,r); int middle=nums[m]; int tmp=middle; for(int i=m-1;i>=l;i--){ tmp+=nums[i]; middle=max(middle,tmp); } tmp=middle; for(int i=m+1;i<=r;i++){ tmp+=nums[i]; middle=max(middle,tmp); } return max(middle,max(left,right)); } public: int maxSubArray(vector<int>& nums) { return divide(nums,0,nums.size()-1); } };
相关文章推荐
- leetcode题解-53. Maximum Subarray && 448. Find All Numbers Disappeared in an Array
- 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
- [LeetCode] 53. Maximum Subarray
- [LeetCode] 53. Maximum Subarray 解题思路
- leetCode刷题归纳-Dynamic Programming(53. Maximum Subarray&& 152. Maximum Product 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
- [LeetCode]53. Maximum Subarray