如何在O(1)中获得数组列表的峰值变化

时间:2016-03-25 07:45:49

标签: java arrays algorithm

我有一个integer

数组
e.g. int a[10]=[3,4,6,8,10,9,6,5,4,2], 

我的意思是数组内的内容会逐渐增加,然后减少,

我想找出变化的最高点(最后更大的值和指数) 例如在上述情况下,10的顺序为1

请注意我们可以通过比较和记录更改来O(n)进行,但我需要帮助才能在O(n)复杂度低于{{1}}时解决此问题。

提前致谢。

2 个答案:

答案 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))