Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在连续数字相差+;1/-1_Algorithm_Data Structures - Fatal编程技术网

Algorithm 在连续数字相差+;1/-1

Algorithm 在连续数字相差+;1/-1,algorithm,data-structures,Algorithm,Data Structures,给定一个一维数组。此数组的每个数与前一个数的差值为+1或-1。示例:数组{5,6,7,6,5,6,7,8,9,8} 您将获得一个数字来搜索它在此数组中的第一个匹配项(例如:搜索8——您的代码应返回7)。不要使用线性搜索 如果没有线性搜索,我可以按如下方式进行尝试: Check if (array[0] == Key) { YES: return 0; } Take a variable: Diff = array[0] // Keep on traver

给定一个一维数组。此数组的每个数与前一个数的差值为+1或-1。示例:数组{5,6,7,6,5,6,7,8,9,8}

您将获得一个数字来搜索它在此数组中的第一个匹配项(例如:搜索8——您的代码应返回7)。不要使用线性搜索

如果没有线性搜索,我可以按如下方式进行尝试:

Check if (array[0] == Key)
{
        YES:
           return 0;
}

Take a variable: Diff = array[0]

// Keep on traversing the array, if Next Number>Current Number
   Diff += 1
   Else
   Diff -= 1

if (Diff==key)
{
    return current_index+1;
}
但是这种方法太通用了。即使键之间的差异不是+-1而是其他值,此方法也可以解决此问题

关于+-1差异,有什么特别的地方可以给我一个更好的解决方案


谢谢。

假设您正在搜索16,数组[0]=8。这意味着您正在搜索的数字不能出现在数组[8]之前,即(target-array[0])。所以你读数组[8],它有13个;这意味着目标不能出现在数组[11]之前。等等+/-1差异使您可以在搜索中提前跳过,因为您知道如果数组[x]=(目标+/-N),则目标编号不能出现在数组[x+N]之前。

您不需要查看列表中的每个编号。假设您正在查找
8
,第一个数字是
5
。您可以安全地执行步骤3,因为8不能在少于三个步骤中发生。你可能会考虑稍微多说一点——比如说6——因为可能有大约1个,但我不知道这是否会更有效率,因为你不确定那是“第一次”的发生。所以,让我们坚持原来的观点:


当你到达新的数字时,你决定下一步要走多大的步-在上面,如果你走了3步,你会找到6步,再走2步(8-6),你会再次找到6步,再走2步,你会找到8步-你就到了!您知道这是第一次出现,因为您跳过的数字不可能是8。而且它只需要三步而不是七步。

选择的答案不是最佳答案。如果你想尽量减少探测的数量(数组查找),你可以做得比从一开始就搜索和采取像
`target-array[i]

因为您可以使用索引查找进行随机访问,所以您可以取得更大的进步。例如,如果在以
a[0]=0
开头的数组中查找9,则可以检查
a[16]
以查看它是否小于或等于0。如果不是,则
a[0..16]
中的任何一个都不能达到9

更大的步幅可以为每个探针提供更多信息(每个探针都可以排除左侧和右侧的标记)。这样,与从左侧搜索时的最小步幅相比,每次搜索时,您可以获得两倍于最小步幅的信息

为了演示从中间搜索优于从左边搜索的优点,下面是一些用Python编程语言编写的工作代码:

def find(arr, value, bias=2):
    # With the bias at 2, new probes are in the middle of the range.
    # Increase the bias to force the search leftwards.
    # A very large bias does the same as searching from left side of the range.
    todo = [(0, len(arr)-1)]  # list of ranges where the value is possible
    while todo:
        low, high = todo.pop()
        if low == high:
            if arr[low] == value: return low
            else: continue
        mid = low + (high - low) // bias
        diff = abs(arr[mid] - value)
        if mid+diff <= high: todo.append([mid + diff, high])
        if mid-diff >= low: todo.append([low, mid - diff])
    raise ValueError('Value is not in the array')

您所描述的“过于通用”的方法仍然是阵列的线性扫描。Zim Zam的anwer就是你要找的。听起来像是家庭作业,所以我给你一个提示。如果数组[a]小于您的密钥,而数组[b]大于您的密钥,您发现了什么?现在要完成这个解决方案,可以使用递归或循环(因为这两种方法是等价的)。请注意,此答案与Zim Zam的不同。@Mitch Wheat:很抱歉,我错过了,更正了格式。@minopret:不,不是作业。@Sandepsing不要选得太快,你可以做得比选择的答案好得多。在我完成我的答案后看到你的答案-iPhone不适合在答案出现时更新答案…此解决方案不是最优的,可以在必要时采取更大的步幅和回溯来改进(仅在不利的情况下)。搜索16,如果
arr[0]=8
,则可以测试
arr[13]
。如果是8或更少,那么你可以再次向前跳13;否则,您需要回溯到
arr[8]
arr[13差异]
@RaymondHettinger之间的某个位置-您给出的代码应用于您选择的示例,性能更差。请参阅我对您的解决方案的评论。可以通过一个常数因子来改进搜索,例如N/(2t),而不是N/t,其中t是目标数,但我认为渐进性不可能比线性时间更好-您总是被限制在向前跳过(或回溯)t因子,所以类似于二进制搜索的东西是不可能的;在最坏的情况下,所有的值(除了您检查的最后一个)都是(t-1)或(t-2),或者是(t+1)或(t+2),在这两种情况下,您都必须检查至少N/2的数组元素。例如:0,1,2,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0-如果搜索2,代码会更糟。因此,“最坏的情况并不比其他算法更糟”是错误的。一般的想法是,从范围的中间位置搜索提供的信息是从范围开始搜索的两倍。在100个元素的数组中,探测
arr[50]
会在两个方向上给出一个排除带,而探测
arr[0]
只会在一个方向上排除标记。使用您给出的示例,我得到了您的“平分”算法与@Zim-ZamO'Pootertoot“至少一步”算法的以下结果:顺序=[找到这个值,你的算法需要N次评估,Zim的需要M次评估]:[6 4 3*],[7 4],[8 4 4],[9 5],[10 3 1*],[11 4 2*],[12 5 2*],[13 5 2*],[14 4 2*])。ZimZam的方法总是比你的好或更好(*),所以我仍然不相信。可能有更好的方法,但不是你用代码给出的方法。
arr = [10, 11, 12, 13, 14, 13, 12, 11, 10, 9, 8, 7, 6, 7, 8]
for i in range(min(arr), max(arr)+1):
    assert arr.index(i) == find(arr, i)