Arrays 在连续元素相差+;1/0/-1

Arrays 在连续元素相差+;1/0/-1,arrays,algorithm,Arrays,Algorithm,我有一个问题,我觉得我太复杂了。我觉得这应该是难以置信的基础,但我在精神上遇到了障碍 问题内容如下: 给定一个整数数组A[1..n],使得A[1]≤ A[n]而且对所有人来说 i、 一,≤ i

我有一个问题,我觉得我太复杂了。我觉得这应该是难以置信的基础,但我在精神上遇到了障碍

问题内容如下:

给定一个整数数组A[1..n],使得A[1]≤ A[n]而且对所有人来说 i、 一,≤ i 我对给定数组的理解如下:您有一个1索引的数组,其中数组的第一个元素小于或等于数组的最后一个元素。数组的每个元素都与前一个元素的in 1相同(因此[2]可以是[1]值的-1、0或+1)

对于这个问题,我有几种解决方案,所有这些都有问题,这里有一个例子来展示我的思考过程

i = 2
while i <= n {
    if (A[i] == x) then 
        break // This can be changed into a less messy case where
              // I don't use break, but this is a rough concept
    else if (abs(A[i] - j) <= 1) then 
        i--
    else 
        i += 2

}
i=2

而我假设我们正在寻找一个数字5。如果数组以[1]=1开始,最好的情况是在[5]中有5,因为它需要至少递增4倍。如果A[5]=3,那么让我们检查A[7],因为它是最接近的可能解。我们如何确定它是[7]?从我们正在寻找的数字中,我们称其为R表示结果,减去我们目前拥有的,我们称其为C表示当前,并将结果添加到i中,如[i+(R-C)]


不幸的是,上述解决方案将适用于除最坏情况外的所有情况(当我们迭代整个数组时)。

在最坏情况下,您必须查看所有数组元素


假设所有元素均为零,但对于单个k,1,a[k]=1除外≤ K≤ N显然,k不知道。然后查找值1。在访问[k]之前,您访问的任何对象的值都为0。您没有访问过的任何元素都可以等于1。

这可以通过修改二进制搜索的形式解决。最重要的前提是:

  • 输入数组始终包含元素
  • 相邻图元之间的距离始终为1
  • 总是有一个包含搜索值的越来越有序的子数组
在此基础上,我们可以采用两种策略:

  • 分而治之:我们可以将搜索范围缩小一半,因为我们总是知道哪个子数组肯定包含指定的值作为递增序列的一部分
  • 限制搜索范围:假设搜索值为3,范围右半部分的限制值为6,我们可以将右限制向左移动3个单元格
As代码(Python,但未经测试):

def搜索半二进制(arr,val):
低电平,向上=0,低电平(arr)-1
在低潮时!=向上:
#减少搜索空间
低+=abs(val-arr[低])
向上-=绝对值(瓦尔-阿勒[向上])
#二进制搜索
中间=(低+高)//2
如果arr[mid]==val:
中途返回
elif val
基本思想由两部分组成:
首先,我们可以减少搜索空间。这利用了阵列的相邻单元可能仅相差一个的事实。也就是说,如果我们的搜索空间的下限与
val
的绝对差值为3,我们可以将下限向右移动至少3,而无需将值移出搜索窗口。上限也是如此。
下一步遵循二进制搜索的基本原理,使用以下循环不变量:
在每次迭代开始时,
arr[low:up+1]
中存在一个数组元素,它等于
val
arr[low]=arr[low]

对于后两种情况,我们可以选择
low=mid+1
(或者分别选择
up=mid-1
)并开始下一次迭代。

它看起来像二进制搜索。对于比O(n)@AlexeiLevenkov更好的搜索算法,没有太多的选择。数组没有排序,所以我不认为这是二进制搜索。顺便说一句,@JohnSmithson虽然没有排序,二进制搜索总是选择目标的一半,所以会在日志时间内找到它。
A[1]≤ [n]
仅表示第一个元素小于或等于最后一个元素(它们是1-索引吗?叹气)。这并不保证任何
i
A[i]
的下一个值不能低于
A[i-1]
<代码>[1,2,1,0,-1,0,1,2]
根据问题约束,似乎是一个完全有效的数组,不是吗?尽管如此,我认为您在下面一段中的建议是有意义的:如果您正在寻找4,并且您所在的元素包含2,那么我们可以跳过下一个元素。如果该元素为0,则跳过前面的3个元素,以此类推。但我认为这对最坏的情况没有帮助。很抱歉编辑,没有看到您的答案。无论哪种方式,都适用同样的逻辑。如果值只能更改1,则可以估计最接近的解决方案在数组中的距离并进行检查。此问题是[1],而不是[i]。如果我没有弄错,则在使用[1 1 2]数组时也会遇到问题。因为它从i=1和值1开始。它检查并发现i=2是下一个可能的解决方案,然后i=3,依此类推,它检查数组的每个元素。你是对的,问题清楚地表明“在最坏的情况下,比查看数组中每个单元格的本机情况更好”。我们也可以在开始时比较A[N]来避免这种情况。我发现了另一个问题,但您的编辑似乎已经解决了这个问题。因此,归根结底,它的意义在于您查看数组中不太明显的元素还是le
def search_semi_binary(arr, val):
    low, up = 0, len(arr) - 1
    while low != up:
        # reduce search space
        low += abs(val - arr[low])
        up -= abs(val - arr[up])

        # binary search
        mid = (low + up) // 2

        if arr[mid] == val:
            return mid
        elif val < arr[mid]:
            # value is definitely in the lower part of the array
            up = mid - 1
        else:
            # value is definitely in the upper part of the array
            low = mid + 1

    return low