给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
思路
(1)解法1是两重for循环暴力求解,所有情况都计算一遍。
(2)解法2一次遍历即可,逻辑暂时说不清。不好的解法
(3)动态规划,合理的解法!2020/4/3
解法1-暴力
时间复杂度是O(n^2)
执行用时 :106 ms, 在所有 Java 提交中击败了5.28%的用户
内存消耗 :72.5 MB, 在所有 Java 提交中击败了5.00%的用户
class Solution {
public int maxSubArray(int[] nums) {
int maxSum = Integer.MIN_VALUE;
for(int i = 0; i < nums.length; i++){
int sum = 0;
for(int j = i; j < nums.length; j++){
sum = sum + nums[j];
if(sum > maxSum){
maxSum = sum;
}
}
}
return maxSum;
}
}
解法2-一次遍历
时间复杂度:O(n)
执行用时 :1 ms, 在所有 Java 提交中击败了99.96%的用户
内存消耗 :49.3 MB, 在所有 Java 提交中击败了5.00%的用户
class Solution {
public int maxSubArray(int[] nums) {
int maxSum = Integer.MIN_VALUE;
int sum = 0;
for(int i = 0; i < nums.length; i++){
sum = sum + nums[i];
if(sum > maxSum){
maxSum = sum;
}
if(sum < 0){
sum = 0;
}
}
return maxSum;
}
}
解法2-2 动态规划
2020/4/3 更新
class Solution {
public int maxSubArray(int[] nums) {
int len = nums.length;
int[] dp = new int[len];
dp[0] = nums[0];
int max = dp[0];
for(int i = 1; i < len; i++){
if(dp[i-1] < 0){
dp[i] = nums[i];
}else{
dp[i] = nums[i] + dp[i-1];
}
if(dp[i] > max){
max = dp[i];
}
}
return max;
}
}
解法3-分治
2020/4/3 更新
class Solution {
public int maxSubArray(int[] nums) {
int left = 0;
int right = 1;
int max = nums[left];
int sum = nums[left];
if(nums.length == 1)
return nums[0];
while(right < nums.length && left < nums.length){
if((sum + nums[right]) < nums[right]) {
left = right;
sum = nums[right];
if(nums[right] > max){
max = nums[right];
}
}else{
sum += nums[right];
if(sum > max){
max = sum;
}
}
right ++;
}
return max;
}
}