leetcode 53. Maximum Subarray

一 题目

  Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

二 分析

  EASY级别,这道题让求最大子数组之和,并且要用两种方法来解,分别是 O(n) 的解法,还有用分治法 Divide and Conquer Approach,先看O(n)的方法。定义两个变量 res 和 sum,其中 res 保存最终要返回的结果,即最大的子数组之和,sum 初始值为0.sum 从头向后遍历, 累加起来, 如果累加的结果小于0, 则退出循环,

public static int maxSubArray(int[] nums) {		
		//coner case
		if(nums== null||nums.length==0 ){
			return 0;
		}
		int res =nums[0];
		int sum =0;
		 for(int i=0;i< nums.length;i++ ){	
			 sum += nums[i];
			 res = Math.max(res, sum);
			 if(sum<0){
				 sum =0;
			 }
		 }
		return res;        
    }

Runtime: 1 ms, faster than 85.43% of Java online submissions for Maximum Subarray.

Memory Usage: 41.9 MB, less than 5.16% of Java online submissions forMaximum Subarray.

时间复杂度:O(n)

分治法:

我们将数组均分为两个部分,那么最大子数组会存在于:左边和右边的最大子数组,从中间开始向左右分别扫描。

这里我没想出来,漏掉中间部分了,看了grandyang 大神的文章。实现起来还是比较啰嗦的。

    假设数组下标有效范围是left到right,将数组分为左半部分下标为(left,mid-1)和右半部分下标为(mid+1,right)以及中间元素下标为mid,接下来递归求出左半部分的最大子序和:lmax=helper(nums,left,mid-1); 右半部分最大子序和rmax=helper(nums,mid+1,right);

接下来再将左半部分右边界,右半部分左边界以及中间元素nums[mid]整合,用了两个循环,先整合左半部分右边界和中间值,再将整合结果与右半部分左边界整合得到整合以后的最大子序和mmax,最后返回mmax,lmax,rmax 的最大值即是要求的最大子序和。代码如下:

private static int helper(int[] nums, int left, int right) {
		if(left>=right){
			return nums[left];
		}
		int mid = (left+right)/2;
		//求左侧最大子数组
		int lmax = helper(nums,left,mid-1);
		//求右侧最大子数组
		int rmax = helper(nums,mid+1,right);
		 int mmax = nums[mid], t = mmax;
		 //求中间,先遍历左侧右边界和中间值
		 for (int i = mid - 1; i >= left; --i) {
	            t += nums[i];
	            mmax = Math.max(mmax, t);
	     }
		 t = mmax;
		 //在遍历右侧
		for(int i= mid+1;i<=right;i++){
			   t += nums[i];
			   mmax = Math.max(mmax, t);
		}//返回最大的
		return Math.max(mmax, Math.max(lmax, rmax));
	}

Runtime: 2 ms, faster than 11.52% of Java online submissions for Maximum Subarray.

Memory Usage: 43.3 MB, less than 5.16% of Java online submissions forMaximum Subarray.

时间复杂度:O(nlogn) .

  虽然比上面慢,而且写起来复杂。但是分治是个重要的算法。只是这里不那么合适。

参考:

https://www.cnblogs.com/grandyang/p/4377150.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值