Arrays 给定排序整数数组,编写一个基于[i]=i的分治算法

Arrays 给定排序整数数组,编写一个基于[i]=i的分治算法,arrays,algorithm,divide-and-conquer,Arrays,Algorithm,Divide And Conquer,给定:排序整数数组,整数都不同-没有重复项 问题:编写一个基于分治的算法(在运行时尽可能好),用于检查数组中是否存在A[i]=i的索引i 我考虑过二进制搜索,它是O(logn)运行时复杂性。 还有比这更快的吗?让我们看一个例子:假设A[i]=i-1表示除k之外的所有索引,其中A[k]=k。仅在一个位置对数组进行采样并不能告诉您关于k的位置的任何信息(除非您碰巧碰到了k) 因此,我不认为最坏情况下的运行时比O(n)更好。让我们看一个例子:假设a[I]=I-1表示除k以外的所有索引,其中a[k]=k

给定:排序整数数组,整数都不同-没有重复项

问题:编写一个基于分治的算法(在运行时尽可能好),用于检查数组中是否存在A[i]=i的索引i

我考虑过二进制搜索,它是O(logn)运行时复杂性。
还有比这更快的吗?

让我们看一个例子:假设A[i]=i-1表示除k之外的所有索引,其中A[k]=k。仅在一个位置对数组进行采样并不能告诉您关于k的位置的任何信息(除非您碰巧碰到了k)


因此,我不认为最坏情况下的运行时比O(n)更好。

让我们看一个例子:假设a[I]=I-1表示除k以外的所有索引,其中a[k]=k。仅在一个位置对数组进行采样并不能告诉您关于k的位置的任何信息(除非您碰巧碰到了k)


因此,我不认为最坏情况下的运行时比O(n)更好。

我认为最好使用二进制搜索作为

1) 给你排序的整数

2) 你需要一个分而治之的算法


3) 二进制搜索的运行时间是O(logn),这比线性搜索好

我认为最好使用二进制搜索作为

1) 给你排序的整数

2) 你需要一个分而治之的算法


3) 二进制搜索的运行时间是O(logn),这比线性搜索要好

要求输入本身排序是不够的。输入数组中没有两个相等值的附加要求是能够使用二进制搜索的必要条件

如果这不是一个条件,则不能使用二进制搜索,如以下示例所示(假设0是第一个索引):

通过二进制搜索,您可以选择中间元素,并决定在它的哪一侧可以有一个
i
,其中
a[i]=i
。问题在于,在上述示例中,解决方案可能位于中心的任一侧:如果
x=2
,则解决方案位于左侧,而当
y=4
时,解决方案位于右侧。因此,分而治之是行不通的。只有在确保输入没有重复值时,分治算法才能工作

除此之外,您还可以立即排除第一个值大于0的输入数组,因为如果没有重复的值,就无法实现
A[i]=i
。类似地,最后一个值小于最后一个索引的输入数组不具有
i
A[i]=i

这种考虑在分而治之的过程中也会起作用。举个例子:

    i:   0 1 2 3 4 5 6 7 8
        -------------------
  A[i]: -4 0 1 2 5 6 7 8 10
首先验证两端的两个值:它们不排除解决方案,因此取索引4处的中间值。由于其值(5)大于索引(4),因此可以忽略从索引4到8的范围。因此,在算法的下一次迭代中,将考虑索引0和3(包括)之间的范围

但最右边索引(3)的值小于3(它是2)。根据上述规则,这意味着不可能有解决方案,因此算法可以就此停止:进行更多的划分将是徒劳的

下面是一个JavaScript实现:

函数hasSelfReference(arr){
let last=arr.length-1;
如果(last<0 | arr[0]>0 | arr[last]>1;
中频(arr[mid]first)返回false;
}否则如果(arr[mid]>mid){
last=mid-1;
如果(arr[last]log(hasSelfReference([-4,0,1,2,5,6,7,8,10]);//false
要求输入本身进行排序是不够的。输入数组中没有两个相等值的附加要求是能够使用二进制搜索的必要条件

如果这不是一个条件,则不能使用二进制搜索,如以下示例所示(假设0是第一个索引):

通过二进制搜索,您可以选择中间元素,并决定在它的哪一侧可以有一个
i
,其中
a[i]=i
。问题在于,在上述示例中,解决方案可能位于中心的任一侧:如果
x=2
,则解决方案位于左侧,而当
y=4
时,解决方案位于右侧。因此,分而治之是行不通的。只有在确保输入没有重复值时,分治算法才能工作

除此之外,您还可以立即排除第一个值大于0的输入数组,因为如果没有重复的值,就无法实现
A[i]=i
。类似地,最后一个值小于最后一个索引的输入数组不具有
i
A[i]=i

这种考虑在分而治之的过程中也会起作用。举个例子:

    i:   0 1 2 3 4 5 6 7 8
        -------------------
  A[i]: -4 0 1 2 5 6 7 8 10
首先验证两端的两个值:它们不排除解决方案,因此取索引4处的中间值。由于其值(5)大于索引(4),因此可以忽略从索引4到8的范围。因此,在算法的下一次迭代中,将考虑索引0和3(包括)之间的范围

但最右边索引(3)的值小于3(它是2)。按照上述原则