zoukankan      html  css  js  c++  java
  • 53.Maximum Subarray

    题目链接:https://leetcode.com/problems/maximum-subarray/description/

    题目大意:给出一串数组,找出其最大连续子序列和,例子如下:

    法一(超时):时间复杂度o(n^2),两层for循环,记录每一个数值后的连续序列的最大和,里层for循环记录当前数值的连续序列的最大和,如果比最大值大,则记录。

    这个方法可以用来解决记录最大序列和的开始和结束下标的问题,即在里层for循环中的当前数值的连续序列的最大和比最大值大时,出现调换时可以在这个步骤中记录开始和结束下标。

    代码如下:

     1 int res = Integer.MIN_VALUE;
     2         for(int i = 0; i < nums.length; i++) {
     3             int cnt = 0;
     4             //对于每一个数值,判断其后面的连续子序列和得到最大值
     5             for(int j = i; j < nums.length; j++) {
     6                 cnt += nums[j];
     7                 if(cnt > res) {
     8                     res = cnt;
     9                 }
    10             }
    11         }
    12         return res;
    View Code

    法二(借鉴):时间复杂度o(n),代码如下(耗时13ms):

     1         //法一
     2 /*        
     3         //这里要把res赋值为最小值,以防序列中负数的出现
     4         int res = Integer.MIN_VALUE;
     5         int sum = 0;
     6         for(int i = 0; i < nums.length; i++) {
     7             if(sum < 0) {
     8                 sum = nums[i];//如果当前值前面的sum<0,则将sum重新赋值为当前值,以此值为新的起点开始计算最大和
     9             }
    10             else {
    11                 sum += nums[i];//否则, 将当前值加入sum中
    12             }
    13             if(sum > res) {
    14                 res = sum;
    15             }
    16         }
    17         return res;*/
    18         //法二
    19         //结论:如果a[i]是负的,那么它不可能代表最优序列的起点,因为任何包含a[i]的作为起点的子序列都可以通过a[i+1]作起点而得到改进。类似地,任何负的子序列不可能是最优子序列的前缀
    20         //如果在内循环中检测到从a[i]到a[j]的子序列是负的,那么可以推进i到j+1。
    21         //在这里的运用也就是当sum<0时,即刻将sum重置为0。
    22         //这里一定要把res赋值为最小值,因为序列中会有负数的情况
    23         int res = Integer.MIN_VALUE;
    24         int sum = 0;
    25         for(int i = 0; i < nums.length; i++) {
    26             sum += nums[i];//System.out.println(sum);
    27             if(sum > res) {
    28                 res = sum;
    29             }
    30             //这里不要用else,因为类似序列{-2,-1}这种就计算不到最后的解
    31             if(sum < 0) {//如果sum<0,则将sum重置,也就是发现sum<0,则说明此序列不会是最大和序列
    32                 sum = 0;
    33             }
    34         }
    35         return res;
    View Code

    法三(借鉴):分治,时间复杂度o(nlogn),参考http://blog.csdn.net/silangquan/article/details/8062229, 代码如下(耗时18ms):

     1     public int maxSubArray(int[] nums) {
     2         return solution(nums, 0, nums.length - 1);
     3     }
     4     
     5     public int solution(int[] a, int left, int right) {
     6         //处理left==right中间值情况
     7         if(left == right) {
     8             return a[left];
     9         }
    10         
    11         int mid = (left + right) / 2;
    12         //递归求左边最大和
    13         int maxLeft = solution(a, left, mid);
    14         //递归求右边最大和
    15         int maxRight = solution(a, mid + 1, right);
    16         
    17         //当前数组左边包含最后一个数的最大和
    18         int maxLeftSum = Integer.MIN_VALUE;
    19         int leftSum = 0;
    20         for(int i = mid; i >= left; i--) {
    21             leftSum += a[i];
    22             if(maxLeftSum < leftSum) {
    23                 maxLeftSum = leftSum;
    24             }
    25         }
    26         
    27         //当前数组右边包含第一个数的最大和
    28         int maxRightSum = Integer.MIN_VALUE;
    29         int rightSum = 0;
    30         for(int i = mid + 1; i <= right; i++) {
    31             rightSum += a[i];
    32             if(maxRightSum < rightSum) {
    33                 maxRightSum = rightSum;
    34             }
    35         }
    36         
    37         //左边最大和,右边最大和,包含左右两边的最大和,返回这三个值中的最大值
    38         int tmp = maxLeft > maxRight ? maxLeft : maxRight;
    39         return tmp > (maxLeftSum + maxRightSum) ? tmp : (maxLeftSum + maxRightSum);
    40     }
    View Code
  • 相关阅读:
    Java 引用类型
    Mysql-5.7.14使用常见问题汇总
    CountBoard 是一个基于Tkinter简单的,开源的桌面日程倒计时应用
    HashMap的源码分析
    redis-cluster源码分析
    redis集群方案
    redis集群命令
    redis集群删除master节点
    redis集群添加master节点
    redis集群部署
  • 原文地址:https://www.cnblogs.com/cing/p/7718940.html
Copyright © 2011-2022 走看看