给定一个数组,其中值只是增加或只是减少或增加然后减少,如何找到这样的数组和数组的最大值和最小值?
最小值只是最小值的最小值。
但如何找到最大值?
一种方法是运行时间为O(n)的线性方法,可以在O(logn)中使用二进制搜索的一些修改来解决吗?
非常感谢任何代码(在java中)。
由于
Nohsib
答案 0 :(得分:6)
在斜率从最大增加到最多减少一次的情况下,当导数首先变为负时,最大值出现。换句话说,x[i]
是满足i
的{{1}}的最小值的最大值。
您确实可以在(x[i+1] - x[i]) < 0
时间内使用二进制搜索找到此内容。在每次迭代时,检查导数是否为负数。如果是,则向左移动,否则向右移动。
答案 1 :(得分:3)
if [1] < [2]
if [end-1] < [end]
min = [1]
max = [end]
else
min = min([1],[end])
max = binarysearch()
else
min = [end]
max = [1]
binarysearch:
take the middle element [mid]
if [mid-1] < [mid] < [mid+1]
binary search [mid - end]
else if [mid-1] > [mid] > [mid+1]
binary search [start - mid]
else
return max([mid-1],[mid],[mid+1]
答案 2 :(得分:2)
通过二分查找,查看它属于哪种情况。 Essentialy尝试找到第一个枢轴点,其中有更大的元素紧跟着更小的说p1,第一个枢轴点,其中有一个较小的元素,紧接着是更大的元素,比如p2。您可以使用二进制搜索(google在旋转的排序数组中进行二进制搜索)
如果p1存在p2不存在,则其递增序列(min = a [0] max = a [n])
如果p2存在且p1不存在,则其递减序列(min = a [n] max = a [0])
如果两者都存在,则增加和减少
min = min(a[0],a[n]) \\first and last
max = a[p1] \\first point where bigger element is followed by a smaller one
答案 3 :(得分:0)
order-statistic tree会做你想要的。它可以在O(lg
以下是订单统计树的java实现的链接(OrderStatisticTree.java)。
然而,考虑到你所说的假设,你可以在你指出的O(1)中找到最小值。最大值可以在O(lg
findMax(array,n,m)
middle = (n + m) / 2;
//check for short array (length 1 or 2) to avoid indexing errors
if middle == n && array(middle) > array(m)
return(array(middle));
else
return(array(m));
if array(middle) > array(middle - 1) //left side of peak
if array(middle) < array(middle + 1) //at peak
return(array(middle));
else
return(findMax(array(middle,m)); //peak is to the right
else //right side of peak
return(findMax(array,n,middle); //peak is to the left
答案 4 :(得分:0)
根据Jean-Bernard Pellerin提出的逻辑
(此代码中仅找到最大值)
public class max_in_increasing_decreasing_array
{
public static int max (int a,int b,int c)
{
int maxi=-1;
if(a>maxi)
maxi=a;
if(b>maxi)
maxi=b;
if(c>maxi)
maxi=c;
return maxi;
}
public static void chkmax(int a[],int low,int high)
{
int mid=(low+high)/2;
if(low==high)
{
System.out.println(a[low]);
return;
}
if(low+1==high)
{
System.out.println(max(a[low],a[high],-1));
return;
}
if((a[mid-1]< a[mid]) && (a[mid] < a[mid+1]))
{
chkmax(a, mid+1, high);
}
else if((a[mid-1]> a[mid]) && (a[mid] > a[mid+1]))
{
chkmax(a, low, mid-1);
}
else
System.out.println(max(a[mid-1],a[mid],a[mid+1]));
}
public static void main(String[] args)
{
int a[]={6,7,4,3,2,1};
chkmax(a, 0,a.length-1);
}
}