如何有效地找到10个最大的子阵列?

时间:2017-04-02 21:58:03

标签: python arrays algorithm

我需要在条件为arr[high] - arr[low] < delta的数组中找到10个最大的子数组(最大长度)。它现在需要50秒(使用Python)。我能够通过修改算法找到最大子阵列,以找到sum < somevalue的最大子阵列。现在,我只是使用for循环并删除每次迭代后找到的最大子数组。我尝试了很多东西,但现在回到现在,因为没有正常工作。数组已排序。

with open(in_file) as f_in, open(out_file, 'w') as f_out:
    dct = {}        
    mainlst = []
    # Read a file and store values in mainlst and map to some strings using dct

    for i in range(10): 
        start = 0
        end = 0
        maxim = 0
        diff = 0
        current = 1
        max_start = 0
        max_end = 0
        while end < len(mainlst)-1:
            end += 1
            diff = mainlst[end] - mainlst[start]                
            current += 1
            while diff > delta:
                start += 1
                diff = mainlst[end] - mainlst[start]
                current -= 1
            if maxim < current:
                maxim = current
                max_start = start
                max_end = end

        print("".join([dct[mainlst[max_start]], ",", str(maxim)]), file=f_out)

        del mainlst[max_start:max_end+1]
编辑:我忘记提及另一个条件了。子阵列不能重叠。

1 个答案:

答案 0 :(得分:2)

O(N lg N)算法:

  1. 遍历每个元素,从小到大,将当前元素设置为A[low]O(N)
  2. 二进制搜索满足不等式A[high]
  3. O(lg N)索引
  4. 将长度和(low, high)对推入优先级队列或任何维持O(lg N)次订单的数据结构
  5. 弹出前10个或前N项,这就是答案
  6. <强> EDITED

    感谢@ m69,使用两个指针可以实现更好的O(N)

    1. 遍历每个元素,从小到大,设置指向最初第一个元素的两个指针lowhigh
    2. high指针向右移动直至A[high] - A[low] >= delta,将长度和(low, high)对推入优先级队列或任何维持{{1}的顺序的数据结构中1}}次。

      对于您的特殊情况,您只需使用大小为10的数组来存储最长的10个子数组,然后您可以使用O(lg N)来维护此数组。

    3. O(1)指针向右移动,重复步骤2.
    4. 请注意,low始终小于或等于low,并且两个指针始终仅向右移动,每次遍历列表一次。所以它是high,或者对于使用优先级队列的一般情况是O(N)