我有一个integer
e.g. int a[10]=[3,4,6,8,10,9,6,5,4,2],
我的意思是数组内的内容会逐渐增加,然后减少,
我想找出变化的最高点(最后更大的值和指数)
例如在上述情况下,10
的顺序为1
,
请注意我们可以通过比较和记录更改来O(n)
进行,但我需要帮助才能在O(n)
复杂度低于{{1}}时解决此问题。
提前致谢。
答案 0 :(得分:2)
我们可以使用Binary search
执行此操作,假设我们处于当前mid
值,通过查看索引mid - 1
和索引mid + 1
,我们可以检查是否序列正在减少或增加,因此我们可以决定我们要在哪一半搜索答案。
我们知道在以下情况下找到了答案:
arr[mid - 1] < arr[mid] && arr[mid + 1] < arr[mid]
伪代码:
int start = 0, end = n;
while(start <= end){
int mid = (start + end)/2;
if(mid - 1 >= 0 && mid + 1 <= n && arr[mid-1] >= arr[mid] && arr[mid] >= arr[mid+1]){
//decreasing part
end = mid-1;
}else if(mid - 1 >= 0 && mid + 1 <= n && arr[mid-1] <= arr[mid] && arr[mid] <= arr[mid+1]){
//increasing part
start = mid+1;
}else{
//answer found, take care of corner cases
cout << arr[mid] << endl;
break;
}
}
这个解决方案的复杂性是O(log2(n)),我不认为更好的解决方案是可能的,因为你需要搜索峰值,而这只能通过比较来完成O( 1)解决方案可能无法实现。
c ++中的演示:http://ideone.com/UXwyaT
答案 1 :(得分:2)
添加到@u_seem_surprised回答,这绝对不能比Omega(logn)
更好。
<强>证明:强>
对于大小为n
的数组,峰的索引具有n
种不同的可能性。
这意味着,对于每个索引i
,我们可以找到一个数组,结果应该是这个索引i
。
使用基于比较的模型,我们需要Omega(log_2(n))
来确定哪些n
值是正确的。
所以我们可以得出结论,这个问题的下限是Omega(log(n))
。