算法在增加,减少,增加和减少的数组中找到最大值和最小值

时间:2011-11-19 20:57:10

标签: java algorithm data-structures

给定一个数组,其中值只是增加或只是减少或增加然后减少,如何找到这样的数组和数组的最大值和最小值?

最小值只是最小值的最小值。

但如何找到最大值?

一种方法是运行时间为O(n)的线性方法,可以在O(logn)中使用二进制搜索的一些修改来解决吗?

非常感谢任何代码(在java中)。

由于
Nohsib

5 个答案:

答案 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 n )中找到任何订单统计,包括最小值和最大值。形成树成本成本O( n lg n ),这与最佳比较排序具有相同的复杂性。添加或删除元素也需要花费O(lg n )。

以下是订单统计树的java实现的链接(OrderStatisticTree.java)。

然而,考虑到你所说的假设,你可以在你指出的O(1)中找到最小值。最大值可以在O(lg )中找到。这是pseduo代码:

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);
}

}