首页 > 学院 > 开发设计 > 正文

六、[LeetCode OJ]Maximum Subarray

2019-11-06 07:33:50
字体:
来源:转载
供稿:网友

【问题描述】

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.

问题来源:Maximum Subarray

【问题分析】

题意:先来理解一下题意,给定一个数组,找出一个连续的子数组,使得子数组之和是最大值。方法一:令max = nums[0],sum = 0。遍历nums,nums[i]与sum相加,如果sum大于max,用sum替换max的值;如果sum小于0了,重置sum为0,最后返回max,时间复杂度为遍历一遍数组O(N)。方法二:分治方法:我们首先定义几个参数:sum——一个数组的和;leftmx——从数组最左开始最大的和;rightmx——从数组最右开始最大的和;mx——数组最大的和。将一个数组A从中间分开,变成两个子数组A1和A2,leftmx1,rightmx1,mx1,sum1表示子数组A1的参数,leftmx2,rightmx2,mx2,sum2表示子数组A2的参数。有以下关系:mx = max(max(mx1, mx2), rightmx1 + leftmx2);leftmx = max(leftmx1, sum1 + leftmx2);rightmx = max(rightmx2, sum2 + rightmx1);sum = sum1 + sum2。对子数组也进行上面的分治操作,直到数组变成不可拆分的单元,即left等于right,此时leftmx = rightmx = mx = sum = nums[left]。最后返回mx。T(n) = 2T(n/2) + O(1),时间复杂度为O(N)。

【源代码】

方法一:
class Solution {public:    int maxSubArray(vector<int>& nums) {        int max = nums[0];        int sum = 0;        int i = 0;        while (i < nums.size()) {        	sum += nums[i];        	if (sum > max) {        		max = sum;        	}        	if (sum < 0) {        		sum = 0;        	}        	i++;        }        return max;    }};方法二(分治方法):
/**sum-------the total sum of the subarray.leftmx----largest sum starting from the left most element.rightmx---largest sum starting ending the right most element.mx--------largest sum of the subarray.**/class Solution {public:    int maxSubArray(vector<int>& nums) {        if (nums.size() == 0) {        	return 0;        }        if (nums.size() == 1) {            return nums[0];        }        int mx,leftmx,rightmx,sum = 0;        maxSubArray(nums, 0, nums.size()-1, mx, leftmx, rightmx, sum);        return mx;    }PRivate:	void maxSubArray(vector<int>& nums, int left, int right, int& mx, int& leftmx, int& rightmx, int& sum) {		if (left == right) {			mx = leftmx = rightmx = sum = nums[left];		} else {			int leftmx1, sum1, rightmx1, mx1 = 0;			int leftmx2, sum2, rightmx2, mx2 = 0;			int mid = (left + right) / 2;			maxSubArray(nums, left, mid, mx1, leftmx1, rightmx1, sum1);			maxSubArray(nums, mid+1, right, mx2, leftmx2, rightmx2, sum2);			mx = max(max(mx1, mx2), rightmx1 + leftmx2);			leftmx = max(leftmx1, sum1 + leftmx2);			rightmx = max(rightmx2, sum2 + rightmx1);			sum = sum1 + sum2;		}	}};
上一篇:递归和尾递归

下一篇:IO流相关概念

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表