码迷,mamicode.com
首页 > 其他好文 > 详细

Maximum Subarray | & ||

时间:2016-07-06 11:54:26      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

Maximum Subarray

 Given an array of integers, find a contiguous subarray which has the largest sum.
 Notice

The subarray should contain at least one number.

Example

Given the array A= [−2,2,−3,4,−1,2,1,−5,3], the contiguous subarray[4,−1,2,1] has the largest sum = 6.

分析:
对于A[i]来讲,为了使得subarray最大,那么A[i]前的值必须要大于1,如果小于0,我们需要从A[i]开始重新,那么subarray的新起点就可能是A[i].

 1 public class Solution {
 2     /**
 3      * @param nums: A list of integers
 4      * @return: A integer indicate the sum of max subarray
 5      */
 6     public int maxSubArray(int[] nums) {
 7         if (nums == null || nums.length == 0) return 0;
 8         int tempMax = nums[0];
 9         int max = nums[0];
10         
11         for (int i = 1; i < nums.length; i++) {
12             if (tempMax > 0) {
13                 tempMax += nums[i];
14             } else {
15                 tempMax = nums[i];
16             }
17             max = Math.max(tempMax, max);
18         } 
19         return max;
20     }
21 }

这里介绍另外一种方法,来自于博客:http://blog.csdn.net/linhuanmars/article/details/21314059

这是一道非常经典的动态规划的题目,用到的思路我们在别的动态规划题目中也很常用,以后我们称为”局部最优和全局最优解法“。
基本思路是这样的,在每一步,我们维护两个变量,一个是全局最优,就是到当前元素为止最优的解是,一个是局部最优,就是必须包含当前元素的最优的解。接下来说说动态规划的递推式(这是动态规划最重要的步骤,递归式出来了,基本上代码框架也就出来了)。假设我们已知第i步的global[i](全局最优)和local[i](局部最优),那么第i+1步的表达式是:
local[i+1]=Math.max(A[i], local[i]+A[i]),就是局部最优是一定要包含当前元素,所以不然就是上一步的局部最优local[i]+当前元素A[i](因为local[i]一定包含第i个元素,所以不违反条件),但是如果local[i]是负的,那么加上他就不如不需要的,所以不然就是直接用A[i];
global[i+1]=Math(local[i+1],global[i]),有了当前一步的局部最优,那么全局最优就是当前的局部最优或者还是原来的全局最优(所有情况都会被涵盖进来,因为最优的解如果不包含当前元素,那么前面会被维护在全局最优里面,如果包含当前元素,那么就是这个局部最优)。

接下来我们分析一下复杂度,时间上只需要扫描一次数组,所以时间复杂度是O(n)。空间上我们可以看出表达式中只需要用到上一步local[i]和global[i]就可以得到下一步的结果,所以我们在实现中可以用一个变量来迭代这个结果,不需要是一个数组,也就是如程序中实现的那样,所以空间复杂度是两个变量(local和global),即O(2)=O(1)。
代码如下: 

 1 public int maxSubArray(int[] A) {
 2     if(A==null || A.length==0)
 3         return 0;
 4     int global = A[0];
 5     int local = A[0];
 6     for(int i=1;i<A.length;i++)
 7     {
 8         local = Math.max(A[i],local+A[i]);
 9         global = Math.max(local,global);
10     }
11     return global;
12 }

 

Maximum Subarray II

Given an array of integers, find two non-overlapping subarrays which have the largest sum. The number in each subarray should be contiguous. Return the largest sum.

Notice

The subarray should contain at least one number.

Example

For given [1, 3, -1, 2, -1, 2], the two subarrays are [1, 3]and [2, -1, 2] or [1, 3, -1, 2] and [2], they both have the largest sum 7.

分析:

既然要有两个不重合的subarray,如果左边一个确定了,右边那个一定是在array的右边部分找。

 1 public class Solution {
 2     /**
 3      * @param nums: A list of integers
 4      * @return: An integer denotes the sum of max two non-overlapping subarrays
 5      * cnblogs.com/beiyeqingteng/
 6      */
 7     public int maxTwoSubArrays(ArrayList<Integer> nums) {
 8         if (nums == null || nums.size() == 0) return 0;
 9         int[] forwardMax = new int[nums.size()];
10 
11         forwardMax[0] = nums.get(0);
12 
13         for (int i = 1; i < nums.size(); i++) {
14             if (forwardMax[i - 1] > 0) {
15                 forwardMax[i] = nums.get(i) + forwardMax[i - 1];
16             } else {
17                 forwardMax[i] = nums.get(i);
18             }
19         }
20 
21         int[] backwardMax = new int[nums.size()];
22 
23         backwardMax[backwardMax.length - 1] = nums.get(nums.size() - 1);
24         for (int i = backwardMax.length - 2; i >= 0; i--) {
25             if (backwardMax[i + 1] > 0) {
26                 backwardMax[i] = nums.get(i) + backwardMax[i + 1];
27             } else {
28                 backwardMax[i] = nums.get(i);
29             }
30         }
31 
32         int[] rightMax = new int[nums.size()];
33 
34         rightMax[rightMax.length - 1] = backwardMax[backwardMax.length - 1];
35         for (int i = rightMax.length - 2; i >= 0; i--) {
36             if (backwardMax[i] >= rightMax[i + 1]) {
37                 rightMax[i] = backwardMax[i];
38             } else {
39                 rightMax[i] = rightMax[i + 1];
40             }
41         }
42         
43         int max = forwardMax[0] + rightMax[1];
44         for (int i = 1; i < nums.size() - 1; i++) {
45             max = Math.max(max, forwardMax[i] + rightMax[i + 1]);
46         }
47         return max;
48     }
49 }

转载请注明出处:cnblogs.com/beiyeqingteng/

 

Maximum Subarray | & ||

标签:

原文地址:http://www.cnblogs.com/beiyeqingteng/p/5632661.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!