• 找出数组中两段不相交的子数组,使其差值最大


    问题描述:

    Given an array of integers. Find two disjoint contiguous sub-arrays such that the absolute difference between the sum of two sub-array is maximum.
    * The sub-arrays should not overlap.
    eg- [2 -1 -2 1 -4 2 8] ans - (-1 -2 1 -4) (2 8), diff = 16

    解答:可在线性时间内解决。

    思路:

    以i为划分点将数组划分为A[1:i]和A[i+1,n]两个部分,统计第一个子数组中的最大子数组值a1和最小子数组值a3,统计第二个子数组中的最大子数组值a4和最小子数组值a2.

    那么 abs(a1-a2)以及abs(a3-a4)中最大的值就是划分为i时候的的最大值了。

    算法步骤:

    首先,从左到右。统计A[1:i]中数值和最大的子数组的数值,用A1[i]来表示。然后从右到左,统计A[j:n]中数值和最小的子数组的数值,用A2[j]来表示。注意此时的i就是划分点

    其次,从左到右。统计A[1:i]中数值和最小的子数组的数值,用A3[i]来表示。然后从右到左,统计A[j:n]中数值和最大的子数组的数值,用A4[j]来表示。注意此时的i就是划分点

    最后,统计abs( A1[i]-A2[i+1] ) 以及abs( A3[i]-A4[i+1] )中的最大值。那就是我们需要的啦。

    时间复杂度说明:

    为什么说上述算法是线性的呢?

    我们注意到只要能说明“统计A[1:i]中数值和最大的子数组的数值,用A1[i]来表示”这一步是线性时间的,那么整个算法也就是线性的。

    下面就来说明一下怎么统计这个。

       1:  max=0; temp=0;
       2:  for(int k=1; k<=n; k++)
       3:  {
       4:  if(A[k]<=0)
       5:  {
       6:     A1[k]=max;
       7:     temp+=A[k];
       8:  }
       9:   
      10:  else
      11:  {
      12:      a1=max+temp+A[k];
      13:      a2=A[k];
      14:   
      15:      if(max<a1)max=a1;
      16:      if(max<a2)max=a2;
      17:      temp=0; A1[k]=max;
      18:  }
      19:   
      20:  }
      21: 

     补充:2014-3-18,今天又看了这个问题,感觉应该不是线性的而是O(n*n),为社么了?因为子数组的切分点不止一个啊!

    哈哈,有质疑是好的,也怪自己当时没仔细考虑,其实是这样的,我们可以把A[1:i]的结果保存下来,计算A[1:i+1]的时候就可以直接用了!!
  • 相关阅读:
    在TCP四次挥手中,为什么客户端发送FIN后,还可以发送报文
    园子今天有个Intel最新漏洞的文章,越来越觉得离谱了
    cdn load fail fallback
    Ethernaut的writeup
    把字符串渲染到页面上有哪些方式?
    VUE基础
    java 多线程 CountDownLatch&CyclicBarrier
    MySQL为什么使用B+树索引
    java 虚拟机
    聊聊C#中的composite模式
  • 原文地址:https://www.cnblogs.com/xubenben/p/3393918.html
Copyright © 2020-2023  润新知