在递增、递减、递增和递减数组中查找最大值和最小值的算法

发布于 2024-12-16 20:43:29 字数 214 浏览 1 评论 0原文

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

最小值只不过是最终值中的最小值。

但如何找到最大值呢?

一种方法是运行时间为 O(n) 的线性方法,可以使用对二分搜索的一些修改在 O(logn) 中解决这个问题吗?

任何代码(java)都受到高度赞赏。

谢谢
诺赫西布

Given an array , in which either the values are only increasing or only decreasing or increasing and then decreasing, How to find the max and min value of such and array?

min value is nothing but the smallest of the end values.

but how to find max value?

One way is the linear approach with running time of O(n), can this be solved in O(logn), using some modification to the binary search?

Any code (in java) is highly appreciated.

Thanks

Nohsib

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

飘过的浮云 2024-12-23 20:43:29

在斜率从增加到减少最多一次的情况下,最大值出现在导数第一次变为负值时。换句话说,x[i] 是满足 (x[i+1] - x[i]) < 的 i 最小值的最大值; 0 。

您确实可以通过二分搜索在 O(log n) 时间内找到它。在每次迭代时,检查导数是否为负。如果是则向左移动,否则向右移动。

In cases where the slope goes from increasing to decreasing at most once, the maximum occurs when the derivative first goes negative. In other words, x[i] is the maximum for the smallest value of i that satisfies (x[i+1] - x[i]) < 0.

You can indeed find this with a binary search in O(log n) time. At every iteration, check whether the derivative is negative. If it is, then move left, otherwise move right.

屋顶上的小猫咪 2024-12-23 20:43:29
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]
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]
情绪少女 2024-12-23 20:43:29

通过二分查找,看看属于哪种情况。本质上,尝试找到第一个枢轴点,其中有较大的元素,紧接着较小的元素,例如 p1,以及第一个枢轴点,其中有较小的元素,紧接着较大的元素,例如 p2。您可以使用二分搜索(谷歌在旋转排序数组中进行二分搜索)来完成这些操作,

如果 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

by binary search, see which case it belongs to. Essentialy try to find the first pivot point where there is bigger element immediately followed by smaller say p1, and first pivot point where there is a smaller element immediately followed by bigger element say p2. You can do these both with binary search (google for binary search in a rotated sorted array)

if p1 exists p2 doesnt, its an increasing sequence (min = a[0] max=a[n])

if p2 exists and p1 doesnt, its a decreasing sequence(min = a[n] max=a[0])

if both exists, its increasing and decreasing

min = min(a[0],a[n]) \\first and last
max = a[p1] \\first point where bigger element is followed by a smaller one
酸甜透明夹心 2024-12-23 20:43:29

订单统计树将做你想要的。它可以在 O(lgn) 中找到任何阶统计量,包括最小值和最大值。形成树的成本为 O(nlgn),这与最佳比较排序的复杂度相同。添加或删除元素的成本也为 O(lgn)。

这是一个链接(OrderStatisticTree.java)顺序统计树的java实现。

然而,考虑到您所陈述的假设,正如您所指出的,可以在 O(1) 中找到最小值。最大值可以在 O(lgn) 中找到。这是伪代码:

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

An order-statistic tree will do what you want. It can find any order statistic, including min and max, in O(lgn). Forming the tree costs costs O(nlgn), which is the same complexity as the best comparison sort. Adding or removing elements also costs O(lgn).

Here is a link (OrderStatisticTree.java) to a java implementation of an order-statistic tree.

However, given the assumptions you've stated, the min can be found in O(1) as you've indicated. The max can be found in O(lgn). Here is the pseduo code:

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
迎风吟唱 2024-12-23 20:43:29

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

}

According to the logic suggested by Jean-Bernard Pellerin

(only max value is found in this code)

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

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文