LeetCode——Maximum Subarray
Description:
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
.
More practice:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
看见这题的第一想法就是决不能用暴力穷举。
然后应该会想到简单的dp。思路就是每次都选择最大的sum(这不是贪心?)。时间复杂度是O(n),空间复杂度是O(1);
public class Solution { public int maxSubArray(int[] nums) { int max = nums[0]; int sum = 0; for(int i=0; i<nums.length; i++) { sum += nums[i]; if(max < sum) max = sum; if(sum < 0) sum = 0; } return max; } }
题目最后还有一个More practice:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
这样的话就要用分治和递归来解。
首先把问题分成若干子问题,找到子问题中的解后逐一合并直到得到整个问题的解。说起来挺简单但是细节问题还是要特别注意的。
时间复杂度是O(nlogn),空间复杂度是O(logn);
public class Solution {
//分治 public int divide(int[] nums, int m, int n) { if(m == n) { return nums[m]; } int mid = m + (n-m)/2; //防止整数溢出 int home = divide(nums, m, mid); int end = divide(nums, mid+1, n); int sum = merge(nums, m, n, mid); return max(sum, max(home, end)); }
//合并 public int merge(int[] nums, int m, int n, int mid) { int leftMax = nums[mid]; int sum = 0; for(int i=mid; i>=m; i--) { sum += nums[i]; if(leftMax < sum) { leftMax = sum; } } sum = 0; int rightMax = nums[mid+1]; for(int i=mid+1; i<=n; i++) { sum += nums[i]; if(rightMax < sum) { rightMax = sum; } } sum = leftMax + rightMax; return sum; } public int max(int a, int b) { return a > b ? a : b; } public int maxSubArray(int[] nums) { if(nums.length <= 0) { return 0; } int res = divide(nums, 0, nums.length-1); return res; } }
分治、dp、贪心有时候傻傻分不清楚。
作者:Pickle
声明:对于转载分享我是没有意见的,出于对博客园社区和作者的尊重一定要保留原文地址哈。
致读者:坚持写博客不容易,写高质量博客更难,我也在不断的学习和进步,希望和所有同路人一道用技术来改变生活。觉得有点用就点个赞哈。