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.
方法一、因为看了这个follow up所以硬逼着自己写了个分治法。感觉像是大二的算法课做过类似的题。
自己的这段代码确实写的非常的冗余。
基本思想如下:一长段数字Maximum Subarray的任务 = 左半边Maximum Subarray+ 右半边Maximum Subarray+(左半边靠中间+右半边靠中间)
时间复杂度O(nlogn) 空间复杂度O(n)
class Solution {
public int maxSubArray(int[] nums) {
return divide_conquer(nums, 0, nums.length);
}
public static int max_three(int a, int b, int c){
if(a>=b){
if(a>=c){
return a;
}
else{
return c;
}
}
else{
if(b>=c){
return b;
}
else{
return c;
}
}
}
public static int divide_conquer(int[] nums, int left, int right){
if ((right-left)<=1){
return nums[left];
}
int max_left = divide_conquer(nums, left, left + (right-left+1)/2);
int max_right = divide_conquer(nums, left + (right-left+1)/2, right);
int max_left_boarder = nums[left+(right-left-1)/2];
int left_boarder_tmp = max_left_boarder;
for (int i = left+(right-left-1)/2-1; i>=left;i--){
left_boarder_tmp += nums[i];
if(max_left_boarder <= left_boarder_tmp){
max_left_boarder = left_boarder_tmp;
}
}
int max_right_boarder = nums[left+(right-left+1)/2];
int right_boarder_tmp = max_right_boarder;
for (int i = left+(right-left+1)/2+1 ; i<right; i++){
right_boarder_tmp += nums[i];
if(max_right_boarder <= right_boarder_tmp){
max_right_boarder = right_boarder_tmp;
}
}
return max_three(max_left, max_right, max_left_boarder+max_right_boarder);
}
}
方法二、动态规划
一直觉得动态规划这个方法,要是能想到,时间复杂度就会特别小,但是确实比较难想到。
相当于我们假设一个转移的状态,一个一个数的过。如果我们发现当前数>当前数+前面的max sum的时候,那么我们的maximum subarray肯定不会包括前面的数了。
时间复杂度:O(n) 空间复杂度: O(1)
之后要再研究一下这个分治法...不知道为什么提示说要用分治法。
class Solution {
public int maxSubArray(int[] nums) {
int max_sum = nums[0];
int max_tmp = nums[0];
for (int i=1; i < nums.length ; i++){
if (max_tmp + nums[i] >= nums[i]){
max_tmp = max_tmp + nums[i];
}
else{
max_tmp = nums[i];
}
if (max_tmp >= max_sum){
max_sum = max_tmp;
}
}
return max_sum;
}
}