zoukankan      html  css  js  c++  java
  • 未排序数组中累加和为给定值的最长子数组长度

    题目:给定一个数组arr,该数组无序,但每个值均为正数,再给定一个正数k。求arr得所有子数组中所有元素相加和为k的最长子数组长度。

    解答:最优解可以做到时间复杂度为o(n),额外空间复杂度为o(1).首先用两个位置来标记子数组的左右两头,记为left和right,开始时都在数组的最左边(left=0,right=0)。整体过程如下:

    1.开始时变量left=0,right=0,代表子数组arr[left......right].

    2.变量sum始终表示子数组arr[left......right]的和。开始时,sum=arr[0],即arr[0....0]的和。

    3.变量len一直记录累加和为k的所有子数组中最大子数组的长度。开始时,len=0.

    4.根据sum与k的比较结果决定是left移动还是right移动,具体如下:

    (1)如果sum==k,说明arr[left.....right]累加和为k,如果arr[left.....right]长度大于len,则跟新len,此时因为数组所有的值都为正数,那么所有从left位置开始,在right之后的位置结束的子数组,累加和一定大于k。所以,令left加1,这表示我们开始考察以left之后的位置开始的子数组,同时令sum=sum-arr[left],sum此时表示arr[left+1.....right]

    (2)如果sum小于k,说明arr[left.....right]还需要加上right后面的值,其和才可能达到k,所以,令right+1,sum+=arr[right].需要注意的是,right+1后是否越界。

    (3)如果sum大于k,说明所有从left位置开始,在right之后的位置结束的子数组,累计和一定大于k,因此,我们考查以left之后的位置开始的子数组,同时令sum-=arr[left],sum此时表示arr[left+1....right]的累计和。

    5.如果right<arr.length,重复步骤4.否则直接返回len,全部过程结束。

    具体的参考代码如下:

     1 public  int  getMaxLength(int[] arr,int k)
     2 {
     3     if(arr==null || arr.length==0 || k<=0)
     4                   return 0;
     5     int left=0;
     6     int right=0;
     7     int sum=arr[0];
     8     int len=0;
     9     while(right<arr.length)
    10    {
    11        if(sum==k)
    12      {
    13         len=Math.max(len,right-left+1);
    14         sum-=arr[left++];
    15      }else if(sum<k)
    16      {
    17          right++;
    18          if(right==arr.length)
    19                break;
    20         sum+=arr[right];
    21     }
    22    else
    23        sum-=arr[left++];
    24    }
    25 
    26   return len;
    27 }
    View Code
  • 相关阅读:
    [JSOI2007]文本生成器 --- AC自动机 + DP
    [POI2000]病毒 --- AC自动机
    [HNOI2011]数学作业 --- 矩阵优化
    [BZOJ4245][ONTAK2015]OR-XOR(贪心)
    [BZOJ4247]挂饰(DP)
    [BZOJ4032][HEOI2015]最短不公共子串(Trie+DP)
    [BZOJ4028][HEOI2015]公约数数列(分块)
    [BZOJ4027][HEOI2015]兔子与樱花(贪心)
    [BZOJ4004][JLOI2015]装备购买(贪心+线性基)
    [HDU5029]Relief grain(树链剖分+线段树)
  • 原文地址:https://www.cnblogs.com/guanling222/p/5771298.html
Copyright © 2011-2022 走看看