剑指 Offer 42. 连续子数组的最大和

输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。

要求时间复杂度为O(n)。

 

示例1:

输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
 

提示:

1 <= arr.length <= 10^5
-100 <= arr[i] <= 100

双指针解法:

 1 class Solution {
 2     public int maxSubArray(int[] nums) {
 3         if(nums.length==0) return 0;
 4         if(nums.length==1) return nums[0];
 5         int i=0,j,len=nums.length,sum,max=Integer.MIN_VALUE;
 6         while(i<len){
 7             sum=0;
 8             j=i;
 9             while(sum>=0&&j<len){
10                 sum+=nums[j++];
11                 max=sum>max?sum:max;
12             }
13             i++;
14         }
15         return max;
16     }
17 }

 递归版解法:

 1 class Solution {
 2     public int helper(int[] nums,int start,int end){
 3         if(start==end) return nums[start];
 4         int mid=(start+end)/2;
 5         int leftSum=helper(nums,start,mid);
 6         int rightSum=helper(nums,mid+1,end);
 7         int crossSum=Crosshelper(nums,start,mid,end);
 8         return Math.max(Math.max(leftSum,rightSum),crossSum);
 9     }
10     public int Crosshelper(int[] nums,int start,int mid,int end){
11         if(start==end) return nums[start];
12         int sum=0;
13         int t=Integer.MIN_VALUE;
14         for(int i=mid;i>=start;i--){
15             sum+=nums[i];
16             t=Math.max(sum,t);
17         }
18         sum=0;
19         int t1=Integer.MIN_VALUE;
20         for(int i=mid+1;i<=end;i++){
21             sum+=nums[i];
22             t1=Math.max(sum,t1);
23         }
24         return t+t1;
25     }
26     public int maxSubArray(int[] nums) {
27         if(nums.length==0) return 0; 
28         return helper(nums,0,nums.length-1);
29     }
30 }

 动态规划解法:

 

 

 

 1 class Solution {
 2     public int maxSubArray(int[] nums) {
 3         if(nums.length==0) return 0; 
 4         int res = nums[0];
 5         for(int i = 1; i < nums.length; i++) {
 6             nums[i] += Math.max(nums[i - 1], 0);
 7             res = Math.max(res, nums[i]);
 8         }
 9         return res;
10     }
11 }
复杂度分析:
时间复杂度 O(N)O(N) : 线性遍历数组 numsnums 即可获得结果,使用 O(N)O(N) 时间。
空间复杂度 O(1)O(1) : 使用常数大小的额外空间。

 

posted @ 2020-07-24 13:12  打屎也不熬夜  阅读(130)  评论(0编辑  收藏  举报