zoukankan      html  css  js  c++  java
  • 剑指 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) : 使用常数大小的额外空间。

  • 相关阅读:
    优美的回文串--全国模拟(二)
    创造新世界--全国模拟(二)
    字符串分类--全国模拟(二)
    平衡数--全国模拟(二)
    最小矩形--全国模拟(二)
    组装三角形--全国模拟(二)
    深入.NET内测题
    面向对象七大设计原则
    创建数据库普通临时表和创建数据库全局变量表和俩者的区别
    使用变量 数据类型转换 逻辑控制语句(begin ...end; case...end; if...else; while)
  • 原文地址:https://www.cnblogs.com/Susie2world/p/13371402.html
Copyright © 2011-2022 走看看