zoukankan      html  css  js  c++  java
  • Continuous Subarray Sum II(LintCode)

    Continuous Subarray Sum II

     

    Given an circular integer array (the next element of the last element is the first element), find a continuous subarray in it, where the sum of numbers is the biggest. Your code should return the index of the first number and the index of the last number.

    If duplicate answers exist, return any of them.

    Example

    Give [3, 1, -100, -3, 4], return [4,1].

     

    先是一个超时了的代码。。虽然剪了枝但还是会超时。

    Time Limit Exceeded 91% test cases passed. Total Runtime: 12957 ms

     1 public class Solution {
     2     /**
     3      * @param A an integer array
     4      * @return  A list of integers includes the index of the first number and the index of the last number
     5      */
     6     public ArrayList<Integer> continuousSubarraySumII(int[] A) {
     7         int l = A.length;
     8         int s = 0;
     9         int e = 0;
    10         int ms = 0;
    11         int me = 0;
    12         int sum = A[0];
    13         int max = A[0];
    14         ArrayList<Integer> list = new ArrayList();
    15         
    16         if(l == 1){
    17             list.add(0);
    18             list.add(0);
    19             return list;
    20         }
    21         
    22         
    23         for(int j = 0;j<l;j++) {
    24             if(A[j] <= 0) continue;
    25             sum = A[j];
    26             s = j;
    27             e = j;
    28             for(int i = (j+1)%l;j!=i;i = (i+1)%l){
    29                 if(A[i] < 0) {
    30                     if(sum > max) {
    31                         max = sum;
    32                         ms = s;
    33                         me = e;
    34                     }
    35                 }
    36             
    37                 if(sum < 0) {
    38                     sum = A[i];
    39                     s = i;
    40                     e = i;
    41                 }else {
    42                     sum += A[i];
    43                     e = i;
    44                 }
    45             }
    46         }
    47 
    48         
    49         if(max > sum) {
    50             list.add(ms);
    51             list.add(me);
    52         }else {
    53             list.add(s);
    54             list.add(e);
    55         }
    56         return list;
    57     }
    58 }
    View Code

    然后很仔细的想了一下。设0<=a<=b<=A.length,最大和区间只有两种情况:[a,b]和[b,A.length-1]U[0,a];只要找出这两种情况下的最大区间和,比较一下大的那个就是所求区间。

    第一种情况就是求不头尾相连数组A的最大和区间。第二种是求不头尾相连A的最小子区间[a+1,b-1](或者说是-A的最大区间和)。

    敲出一段乱糟糟的代码终于AC了,容我去撸一把。

    Accepted Total Runtime: 12746 ms 100% test cases passed.

     1 public class Solution {
     2     /**
     3      * @param A an integer array
     4      * @return  A list of integers includes the index of the first number and the index of the last number
     5      */
     6     public ArrayList<Integer> continuousSubarraySumII(int[] A) {
     7         int[] nums = A;
     8         int sum = nums[0];
     9         int allsum = nums[0];
    10         int max = nums[0];
    11         int min = nums[0];
    12         int msum = nums[0];
    13         int mins = 0;
    14         int mine = 0;
    15         int s1 = 0;
    16         int e1 = 0;
    17         int s = 0;
    18         int e = 0;
    19         int ms = 0;
    20         int me = 0;
    21         ArrayList<Integer> list = new ArrayList<Integer>();
    22         
    23         for(int i = 1 ;i < nums.length ;i++) {
    24             allsum += nums[i];
    25             if(nums[i] < 0) {
    26                 if(sum > max) {
    27                     max = sum;
    28                     ms = s;
    29                     me = e;
    30                 }
    31             }
    32             
    33             if(nums[i] > 0) {
    34                 if(msum < min) {
    35                     min = msum;
    36                     mins = s1;
    37                     mine = e1;
    38                 }
    39             }
    40             
    41             if(sum < 0) {
    42                 sum = nums[i];
    43                 s = i;
    44                 e = i;
    45             }else {
    46                 sum+=nums[i];
    47                 e++;
    48             }
    49             
    50             if(msum > 0) {
    51                 msum = nums[i];
    52                 s1 = i;
    53                 e1 = i;
    54             }else {
    55                 msum+=nums[i];
    56                 e1++;
    57             }
    58         }
    59         
    60         if(sum > max) {
    61             max = sum;
    62             ms = s;
    63             me = e;
    64         }
    65         if(msum < min) {
    66             min = msum;
    67             mins = s1;
    68             mine = e1;
    69         }
    70         int val = allsum - min;
    71         if(val > max && (mins != 0 && mine != A.length-1)) {
    72             ms = mine + 1;
    73             me = mins - 1;
    74         }
    75         
    76         list.add(ms);
    77         list.add(me);
    78         return list;
    79     }
    80 }
    View Code

    还有一个想法是将A拷贝一份接上,然后相当于求这整个数组的最大和区间。想法是设置一个int flag允许遍历数组尾部两次;同时限制区间长度不能超过A.length。但是WA了。快折腾一下午了实在不想搞了先放着以后想起来再说把。

    Wrong Answer Total Runtime: 8168 ms 78% test cases passed.

     1 public class Solution {
     2     /**
     3      * @param A an integer array
     4      * @return  A list of integers includes the index of the first number and the index of the last number
     5      */
     6     public ArrayList<Integer> continuousSubarraySumII(int[] A) {
     7         int l = A.length;
     8         int s = 0;
     9         int e = 0;
    10         int ms = 0;
    11         int me = 0;
    12         int sum = A[0];
    13         int max = A[0];
    14         int flag = 2;//允许遍历数组尾部2次
    15         ArrayList<Integer> list = new ArrayList();
    16         
    17         if(l == 1){
    18             list.add(0);
    19             list.add(0);
    20             return list;
    21         }
    22         
    23         int i = 1;
    24         while(flag > 0) {
    25             if(i == l - 1) flag--;
    26             if(A[i] < 0) {
    27                 if(sum > max) {
    28                     max = sum;
    29                     ms = s;
    30                     me = e;
    31                 }
    32             }
    33             
    34             if(sum < 0) {
    35                 sum = A[i];
    36                 s = i;
    37                 e = 0;
    38             }else {
    39                 if(e + 1 > l - 1) break;
    40                 sum += A[i];
    41                 e++;
    42             }
    43             
    44             i = (i + 1) % l;
    45         }
    46         
    47         
    48         if(max > sum) {
    49             list.add(ms);
    50             list.add((me+ms)%l);
    51         }else {
    52             list.add(s);
    53             list.add((e+s)%l);
    54         }
    55         return list;
    56     }
    57 }
    View Code
  • 相关阅读:
    设计模式学习笔记之一:策略模式
    向上转型和向下转型
    html readonly和disabled的区别
    如何自定义JSR-303标准的validator
    vue 组件属性props,特性驼峰命名,连接线使用
    laydate中设置动态改变max与min值的方法
    浅谈JS中 reduce() 的用法
    jq 实时监听input输入框的变化
    npm install --save 和 npm install -d的区别
    vue中html、js、vue文件之间的简单引用与关系
  • 原文地址:https://www.cnblogs.com/FJH1994/p/5026398.html
Copyright © 2011-2022 走看看