Java 求递增、递减、递增和递减数组中最大值和最小值的算法
给定一个数组,该数组中的值要么是递增的,要么是递减的,要么是先递增后递减的,如何求该数组的最大值和最小值 最小值只是最小的结束值 但是如何找到最大值呢 一种方法是运行时间为O(n)的线性方法,通过对二进制搜索进行一些修改,可以在O(logn)中解决这个问题吗 任何代码(java)都非常受欢迎 谢谢Java 求递增、递减、递增和递减数组中最大值和最小值的算法,java,algorithm,data-structures,Java,Algorithm,Data Structures,给定一个数组,该数组中的值要么是递增的,要么是递减的,要么是先递增后递减的,如何求该数组的最大值和最小值 最小值只是最小的结束值 但是如何找到最大值呢 一种方法是运行时间为O(n)的线性方法,通过对二进制搜索进行一些修改,可以在O(logn)中解决这个问题吗 任何代码(java)都非常受欢迎 谢谢 诺西比在斜率最多从增加到减少一次的情况下,最大值出现在导数第一次变为负值时。换句话说,x[i]是满足(x[i+1]-x[i])
诺西比在斜率最多从增加到减少一次的情况下,最大值出现在导数第一次变为负值时。换句话说,
x[i]
是满足(x[i+1]-x[i])<0
的i
最小值的最大值
您确实可以在
O(logn)
time中通过二进制搜索找到这一点。在每次迭代中,检查导数是否为负。如果是,则向左移动,否则向右移动。如果斜率最多从增大到减小一次,则最大值出现在导数第一次变为负值时。换句话说,x[i]
是满足(x[i+1]-x[i])<0
的i
最小值的最大值
您确实可以在
O(logn)
time中通过二进制搜索找到这一点。在每次迭代中,检查导数是否为负。如果是,则向左移动,否则向右移动。通过二进制搜索,查看它属于哪种情况。基本上,试着找到第一个轴心点,即较大的元素紧跟较小的元素(如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
通过二进制搜索,查看它属于哪种情况。基本上,试着找到第一个轴心点,即较大的元素紧跟较小的元素(如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
如果[1]<[2]
如果[end-1]<[end]
最小=[1]
max=[结束]
其他的
最小值=最小值([1],[end])
max=binarysearch()
其他的
最小=[结束]
max=[1]
二进制搜索:
以中间元素[mid]为例
如果[mid-1]<[mid]<[mid+1]
二进制搜索[中间端]
如果[mid-1]>[mid]>[mid+1],则为else
二进制搜索[开始-中间]
其他的
返回最大值([mid-1]、[mid]、[mid+1]
如果[1]<[2]
如果[end-1]<[end]
最小=[1]
max=[结束]
其他的
最小值=最小值([1],[end])
max=binarysearch()
其他的
最小=[结束]
max=[1]
二进制搜索:
以中间元素[mid]为例
如果[mid-1]<[mid]<[mid+1]
二进制搜索[中间端]
如果[mid-1]>[mid]>[mid+1],则为else
二进制搜索[开始-中间]
其他的
返回最大值([mid-1]、[mid]、[mid+1]
An将执行您想要的操作。它可以在O(lgn)中找到任何订单统计信息,包括最小和最大值。形成树的成本为O(nlgn),这与最佳比较排序的复杂性相同。添加或删除元素的成本也为O(lgn)
下面是一个指向订单统计树的java实现的链接()
然而,根据您所述的假设,如您所示,最小值可以在O(1)中找到。最大值可以在O(lgn)中找到。以下是psedou代码:
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
findMax(数组,n,m)
中间=(n+m)/2;
//检查短数组(长度1或2)以避免索引错误
如果中间==n&&数组(中间)>数组(m)
返回(数组(中间));
其他的
返回(数组(m));
如果数组(中间)>数组(中间-1)//峰值左侧
如果数组(中间)<数组(中间+1)//处于峰值
返回(数组(中间));
其他的
return(findMax(数组(中间,m));//峰值在右边
else//山顶右侧
return(findMax(数组,n,中间);//峰值在左边
An将执行您想要的操作。它可以在O(lgn)中找到任何订单统计信息,包括最小和最大值。形成树的成本为O(nlgn),这与最佳比较排序的复杂性相同。添加或删除元素的成本也为O(lgn)
下面是一个指向订单统计树的java实现的链接()
然而,根据您所述的假设,如您所示,最小值可以在O(1)中找到。最大值可以在O(lgn)中找到。以下是psedou代码:
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
findMax(数组,n,m)
中间=(n+m)/2;
//检查短数组(长度1或2)以避免索引错误
如果中间==n&&数组(中间)>数组(m)
返回(数组(中间));
其他的
返回(数组(m));
如果数组(中间)>数组(中间-1)//峰值左侧
如果数组(中间)<数组(中间+1)//处于峰值
返回(数组(中间));
其他的
return(findMax(数组(中间,m));//峰值在右边
else//山顶右侧
return(findMax(数组,n,中间);//峰值在左边
根据Jean-Bernard Pellerin提出的逻辑
(在此代码中仅找到最大值)
递增递减数组中的公共类最大值
{
公共静态整数最大值(整数a、整数b、整数c)
{
int maxi=-1;
如果(a>maxi)
maxi=a;
如果(b>maxi)
maxi=b;
如果(c>maxi)
maxi=c;
返回最大值;
}
公共静态无效chkmax(整数a[],整数低,整数高)
{
int mid=(低+高)/2;
如果(低==高)
{
System.out.println(a[低]);
返回;
}
如果(低+1==高)
{
System.out.pri