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.

Idea 1: For all pairs of integers i and j satisfying 0 <= i  <= j < nums.length, check whether the sum of nums[i..j] is greater than the maximum sum so far, take advange of:

  sum of nums[i..j] = sum of nums[i..j-1] + nums[j]

the sum of all continuous subarray starting at i can be calculated in O(n), hence we have a quadratic algorithm.

Time complexity: O(n2)

Space complexity: O(1)

class Solution {
public int maxSubArray(int[] nums) {
int sz = nums.length;
int maxSumSoFar = Integer.MIN_VALUE; for(int i = 0; i < sz; ++i) {
int sumStartHere = 0;
for(int j = i; j < sz; ++j) {
sumStartHere += nums[j];
maxSumSoFar = Math.max(maxSumSoFar, sumStartHere);
}
}
return maxSumSoFar;
}
}

Idea 1.a:  With the help of a cumulative sum array, cumarr[0...i], which can be computed in linear time,  it allows the sum to be computed quickly,

sum[i..j] = cumarr[j] - cumarr[i-1].

Time complexity: O(n2)

Space complexity: O(n)

class Solution {
public int maxSubArray(int[] nums) {
if(nums == null || nums.length < 1) return 0;
int sz = nums.length;
int[] cumuSum = new int[sz]; cumuSum[0] = nums[0];
for(int i = 1; i < sz; ++i) {
cumuSum[i] = cumuSum[i-1] + nums[i];
} int maxSumSoFar = Integer.MIN_VALUE;
for(int i = 0; i < sz; ++i) {
for(int j = i; j < sz; ++j) {
int previousSum = 0;
if(i > 0) {
previousSum = cumuSum[i-1];
}
maxSumSoFar = Math.max(maxSumSoFar, cumuSum[j] - previousSum);
}
} return maxSumSoFar;
}
}
class Solution {
public int maxSubArray(int[] nums) {
if(nums == null || nums.length < 1) return 0;
int sz = nums.length;
int[] cumuSum = new int[sz]; cumuSum[0] = nums[0];
for(int i = 1; i < sz; ++i) {
cumuSum[i] = cumuSum[i-1] + nums[i];
} int maxSumSoFar = Integer.MIN_VALUE;
for(int j = 0; j < sz; ++j) {
maxSumSoFar = Math.max(maxSumSoFar, cumuSum[j]);
for(int i = 1; i <= j; ++i) {
maxSumSoFar = Math.max(maxSumSoFar, cumuSum[j] - cumuSum[i-1]);
}
} return maxSumSoFar;
}
}

Idea 2: divide and conquer. Divide into two subproblems, recusively find the maximum in subvectors(max[i..k], max[k..j]) and find the maximum of crossing subvectors(max[i..k..j]), return the max of max[i..k], max[k..j] and max[i..k..j].

Time complexity: O(nlgn)

Space complexity: O(lgn) the stack

class Solution {
private int maxSubArrayHelper(int[] nums, int l, int u) {
if(l >= u) return Integer.MIN_VALUE;
int mid = l + (u - l)/2; int leftMaxSum = nums[mid];
int sum = 0;
for(int left = mid; left >=l; --left) {
sum += nums[left];
leftMaxSum = Math.max(leftMaxSum, sum);
} int rightMaxSum = 0;
sum = 0;
for(int right = mid+1; right < u; ++right) {
sum += nums[right];
rightMaxSum = Math.max(rightMaxSum, sum);
} return Math.max(leftMaxSum + rightMaxSum,
Math.max(maxSubArrayHelper(nums, l, mid), maxSubArrayHelper(nums, mid+1, u)));
} public int maxSubArray(int[] nums) {
return maxSubArrayHelper(nums, 0, nums.length);
}
}

Idea 3: Extend the solution to the next element in the array. How can we extend a solution for nums[0...i-1] to nums[0..i].

The key is the max sum ended in each element, if extending to the next element,

maxHere(i) = Math.max( maxHere(i-1) + nums[i], nums[i])

maxSoFar = Math.max(maxSoFar, maxHere)

Time compleixty: O(n)

Space complexity: O(1)

class Solution {
public int maxSubArray(int[] nums) {
int maxHere = 0;
int maxSoFar = Integer.MIN_VALUE; for(int num: nums) {
maxHere = Math.max(maxHere, 0) + num;
maxSoFar = Math.max(maxSoFar, maxHere);
} return maxSoFar;
}
}

Idea 3.a: Use the cumulative sum,

maxHere = cumuSum(i) - minCumuSum

cumuSum(i) = cumuSum(i-1) + nums[i]

maxSoFar = Math.max(maxSoFar, maxHere) = Math.max(maxSoFar, cumuSum - minCumuSum)

Time compleixty: O(n)

Space complexity: O(1)

class Solution {
public int maxSubArray(int[] nums) {
int min = 0;
int cumuSum = 0;
int maxSoFar = Integer.MIN_VALUE; for(int num: nums) {
cumuSum += num;
maxSoFar = Math.max(maxSoFar, cumuSum - min);
min = Math.min(min, cumuSum);
} return maxSoFar;
}
}

Maximum Subarray LT53的更多相关文章

  1. [LintCode] Maximum Subarray 最大子数组

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

  2. 【leetcode】Maximum Subarray (53)

    1.   Maximum Subarray (#53) Find the contiguous subarray within an array (containing at least one nu ...

  3. 算法:寻找maximum subarray

    <算法导论>一书中演示分治算法的第二个例子,第一个例子是递归排序,较为简单.寻找maximum subarray稍微复杂点. 题目是这样的:给定序列x = [1, -4, 4, 4, 5, ...

  4. LEETCODE —— Maximum Subarray [一维DP]

    Maximum Subarray Find the contiguous subarray within an array (containing at least one number) which ...

  5. 【leetcode】Maximum Subarray

    Maximum Subarray Find the contiguous subarray within an array (containing at least one number) which ...

  6. maximum subarray problem

    In computer science, the maximum subarray problem is the task of finding the contiguous subarray wit ...

  7. (转)Maximum subarray problem--Kadane’s Algorithm

    转自:http://kartikkukreja.wordpress.com/2013/06/17/kadanes-algorithm/ 本来打算自己写的,后来看到上述链接的博客已经说得很清楚了,就不重 ...

  8. 3月7日 Maximum Subarray

    间隔2天,继续开始写LeetCodeOj. 原题: Maximum Subarray 其实这题很早就看了,也知道怎么做,在<编程珠玑>中有提到,求最大连续子序列,其实只需要O(n)的复杂度 ...

  9. LeetCode: Maximum Product Subarray && Maximum Subarray &子序列相关

    Maximum Product Subarray Title: Find the contiguous subarray within an array (containing at least on ...

随机推荐

  1. Nodejs this详解

    [Nodejs this详解] Nodejs中, 文件层this,指向的是module.export. 函数层this,指向的是global对象. 参考:http://www.jb51.net/art ...

  2. Typechecking With PropTypes

    [Typechecking With PropTypes] 1.props类型检查 React has some built-in typechecking abilities. To run typ ...

  3. WPF HyperLink链接下划线隐藏

    两种方法: 1.在Grid标签内添加资源样式. <Grid.Resources> <Style TargetType="Hyperlink"> <Se ...

  4. vue element upload上传、清除等

    如果项目中可以使用file-list,那我们可以点击file-list删除文件列表: 有时候项目中是不要这个文件列表的,所以在上传成功以后,文件列表一直存在,要重新上传就必须刷新页面,所以我们需要手动 ...

  5. 对arm裸板调试的理解

    由于arm芯片一般都包含的由jtag调试这项功能,cpu向外部发出信号时,一般都要同jtag发送出去,它就像一个路口的交警一样,能够控制车辆的运行,当然在arm中指的是cpu发出的数据和地址,我们在调 ...

  6. gdb打印C++容器

    将以下内容保存成 .gdbinit 文件放到你的根目录,或者在gdb中source这个文件可以加载. 直接print容器即可. # # STL GDB evaluators/views/utiliti ...

  7. TZOJ 3295 括号序列(区间DP)

    描述 给定一串字符串,只由 “[”.“]” .“(”.“)”四个字符构成.现在让你尽量少的添加括号,得到一个规则的序列. 例如:“()”.“[]”.“(())”.“([])”.“()[]”.“()[( ...

  8. #define宏重定义

    #define A 1 在同一个工程的另外一个文件里又定义了#define A 2 并不会报错(2010vs) 亲测可用 但是最后该宏变量A的值 ,应该是预处理-----顺序处理------最后一个运 ...

  9. Django的视图函数和路由系统中一些没有用过的小点

    1.request对象 print("返回用户访问的url,但是不包括域名",request.path_info) print("返回请求的方法,全大写",re ...

  10. swift - 本地通知2 - 啰嗦版

    1. import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var windo ...