Arrays 左右旋转阵列后最长递增子阵列的长度

Arrays 左右旋转阵列后最长递增子阵列的长度,arrays,algorithm,data-structures,priority-queue,Arrays,Algorithm,Data Structures,Priority Queue,我在一个有竞争力的编程平台上遇到了这个问题: 给定长度为N和Q的查询数组,其中查询是数组的左旋转或右旋转。查找每次旋转后数组中最长子数组的长度。 虽然O(N*Q)方法是一个可接受的答案,但我忍不住认为必须有一种更快的方法,因为每次旋转只会修改2个潜在子序列的长度 我考虑复制数组并附加重复数组以获得长度为2N的数组: 那么如果我取一个大小为N的窗口: 在0次旋转的情况下,答案是窗口开始的[0,N-1]范围内最长的递增子阵列 如果左旋转1次,答案是[1,N]范围内最长的子阵列,即将窗口向右移动1

我在一个有竞争力的编程平台上遇到了这个问题:

给定长度为N和Q的查询数组,其中查询是数组的左旋转或右旋转。查找每次旋转后数组中最长子数组的长度。

虽然O(N*Q)方法是一个可接受的答案,但我忍不住认为必须有一种更快的方法,因为每次旋转只会修改2个潜在子序列的长度

我考虑复制数组并附加重复数组以获得长度为2N的数组:

那么如果我取一个大小为N的窗口:

  • 在0次旋转的情况下,答案是窗口开始的[0,N-1]范围内最长的递增子阵列
  • 如果左旋转1次,答案是[1,N]范围内最长的子阵列,即将窗口向右移动1个单位
  • 在k个向左旋转的情况下,答案将在[k,N-1+k]范围内,这将使窗口从初始位置向右移动k个单位
我计划通过将窗口向右移动1个单位来保存所有可能查询的答案,直到我检查了N-1个左旋转

为[0,N-1]范围寻找最长的子阵列将是O(N),但我无法减少每次窗口移动后所花费的时间

我曾想过使用一个优先级队列,在这个队列中,我将存储窗口中的每个索引以及以所述索引为起点的最长子数组的长度,并使用子数组的长度作为优先级。我在换班后更新队列时遇到问题。我最初认为我不必进行太多的更新,从而将算法的复杂度降低到O(nlogn),但这里我不更新在窗口移动之前添加的子数组

我觉得如果优先级队列管理得当,预处理的复杂性可以降低到O(nlogn),每个查询的复杂性可以降低到O(1)


编辑:问题实际上是关于最长的递增子数组,但我使用了subsequence,而不是使用在编辑后已更正的单词subarray。

考虑重复序列(如您所建议的)。尝试对元素进行分组,这样如果ai,那么静态数组的O(n)时间复杂度到底是怎么得到的?你说的“我忍不住认为一定有一种更快的方法,因为每次旋转只会修改2个潜在子序列的长度”是什么意思?从序列中删除第一个元素可能会影响2个以上的递增子序列(几乎所有子序列)。基本上,您的查询与在末尾添加一个元素(这可以在O(logn)中轻松处理)和从开头删除一个元素(这才是真正的问题)是一样的。我不确定是否存在任何有效的算法,原因是要计算O(n logn)中的LIS,通常使用基于先前结果的动态规划。如果在末尾添加新元素,则可以再次重用它们。如果删除第一个元素,所有计算值都可能更改,因此为了能够添加新的元素,应更新DP结果。由于所有N值都可能发生变化,因此似乎很难将时间减少到O(N)以下。另一方面,为了避免删除开头,您需要独立计算所有的移位,但不幸的是,其中有O(n),因此在O(n^2)以下进行计算也会有问题。@Maras抱歉,这是我的错误。我想问一下子阵列,但我把它和子序列搞混了。我对问题进行了编辑以反映这一点。