• 距离最长的有序对问题


    问题描述:

      给定一个无序数组A[0..N-1],求出它的最长子串A[j..k],满足Aj < Ak。


    算法0:
      直接枚举j、k,时间复杂度是O(n^2)。


    算法1:
      注意到一个性质,对于子串A[i..j..m],如果有Ai <= Aj,那么A[i..j..m]必然优于A[j..m],j就不可能是起始点。所以所求子串的起始点j必然满足Ai > Aj (i < j),以下是求出所有起始点的算法:

    head_pos = [0]
    min = A[0]
        for i in range(1..N):
            if A[i] < min:
                head_pos.append(i)
         min = A[i]
    

      可以发现,所求出的起始点数组实际上是以A[0]开始的一个单调递减序列。
       接下来问题就变得简单了,我们只要枚举子串的终止点k,并找出第一个满足A[j] < A[k]的起始点j即可,由于head_pos的单调性,我们可以用二分查找在O(logn)时间内找出j,于是整个算法的复杂度为O(nlogn),辅助空间为O(n)。


    算法2:
      首先构造出所有下标值的排序数组P[0..N-1],使得A[P[j]] <= A[P[k]] (j < k),构建算法如下:
        1. 令P[0..N-1] = 0, 1, 2, ..., N-1
        2. 根据S[P[i]]的值对P进行排序

      上面的排序如果使用计数排序的话,构建排序数组的复杂度为O(n)。
      于是问题转变为:在排序数组P中找出(Pi - Pj) 的最大值(i < j 并且 A[Pi] != A[Pj]),这一步也可以在O(n)内解决:

    minp = P[0]
    minl = 0
    for i in range(1..N):
        if P[i] < P[minp]:
            minp = P[i]
        else:
            minl = min(minl, P[i] - minp)
    

      于是算法总复杂度为O(n),辅助空间O(n)。

  • 相关阅读:
    索引
    varnish它是一款高性能的http缓存服务器
    前端性能优化浅谈
    锁机制-SQL Server 数据库
    NET Core中NuGet包
    “干掉” if...else
    混搭.NET技术
    MONO x64 amd_x64
    跨平台移动开发UI语言 -XAML
    使用LinqToExcel读取Excel
  • 原文地址:https://www.cnblogs.com/richselian/p/2447152.html
Copyright © 2020-2023  润新知