Python 在O(n)或更短的时间内从列表中的任何索引开始,两个青蛙可以创建的最大距离?

Python 在O(n)或更短的时间内从列表中的任何索引开始,两个青蛙可以创建的最大距离?,python,sub-array,contiguous,Python,Sub Array,Contiguous,有一个挑战,我想知道是否可以在O(n)时间或更短的时间内完成。描述如下: 蛙跳 2个青蛙可以从给定输入数组中的任何索引开始。该函数应返回这些青蛙通过让它们跳得更远而在它们之间可能产生的最大距离(两者的索引值之间的差异) 从对方那里 青蛙只能在价值更高的元素上跳跃,或者在一些相同高度的元素上跳跃,它们不能跳过任何元素 输入:[1,5,5,2,6] 产出:3。最大距离3是由产卵位置3(0索引)和左蛙跳直到索引1和右蛙跳直到索引4创建的 len(输入_数组)介于2和200000之间。 数组中的值是介于

有一个挑战,我想知道是否可以在O(n)时间或更短的时间内完成。描述如下:

蛙跳

2个青蛙可以从给定输入数组中的任何索引开始。该函数应返回这些青蛙通过让它们跳得更远而在它们之间可能产生的最大距离(两者的索引值之间的差异) 从对方那里

青蛙只能在价值更高的元素上跳跃,或者在一些相同高度的元素上跳跃,它们不能跳过任何元素

输入:[1,5,5,2,6]

产出:3。最大距离3是由产卵位置3(0索引)和左蛙跳直到索引1和右蛙跳直到索引4创建的

len(输入_数组)介于2和200000之间。 数组中的值是介于1和1 000之间的整数

实际上,这里的挑战似乎是找到最长的连续子序列,这样它首先是非递增的,然后是非递减的(行为的变化点是起始指数)。这似乎是最高和子阵列任务的变体

我的最佳解决方案是O(n logn),通过迭代数组中的所有索引,并携带一个
max_值
,该值根据两个青蛙可以从该迭代的索引跳多远进行检查


这可以在O(n)或更少的时间复杂度下完成吗?

我也试图解决同样的问题,我已经完成了下面的代码。老实说,我不知道是否有可能做得更好,或者我是否错过了任何角逐


公共类蛙跳{
公共int findMaxDistance(int[]块){
整数maxSum=null;
int启动;
int最大距离=0;
int i;
如果(块长度<2){
返回块长度;
}
i=0;
而(i=0)和&(imaxSum)){
最大和=和;
maxDistance=i-开始+1;
}
} 
返回最大距离;
}
公共静态void main(字符串[]args){
int[]t={2,6,8,5};
System.out.println(新的FrogLongestJump().findMaxDistance(t));
int[]t2={1,5,5,2,6};
System.out.println(新的FrogLongestJump().findMaxDistance(t2));
}
}
这是因为青蛙只能跳得更高,但如果它们只能跳得更低,第一个环将与第二个环交换

这段代码基于这样的假设:要找到最大距离,必须找到数组中最长的连续部分,在该部分形成一个“U”,因此从顶部开始,然后向下到底部,然后向上到下一个顶部

重复元素会使问题复杂化,为了解决这个问题,每次“U”在重复元素中停止时,在检查下一个“U”时,您首先返回重复元素(第一个子循环)。

我的解决方案如下:

public int findMaxDistance(int[] blocks) {
    final int numBlocks = blocks.length;

    return IntStream.range(0, blocks.length)
            .parallel()
            .map(i -> {
                int leftSum = 0;
                if (i != 0) {
                    int leftPos = i;
                    while (leftPos-1 >= 0 && blocks[leftPos-1] >= blocks[leftPos]) {
                        leftSum++;
                        leftPos--;
                    }
                }

                int rightSum = 0;
                int rightPos = i;
                while (rightPos+1 < numBlocks && blocks[rightPos+1] >= blocks[rightPos]) {
                    rightSum++;
                    rightPos++;
                }

        
                return rightSum + leftSum;
            }
            )
            .max().getAsInt();

}
public int findMaxDistance(int[]块){
最终int numBlocks=blocks.length;
返回IntStream.range(0,blocks.length)
.parallel()
.map(i->{
int leftSum=0;
如果(i!=0){
int-leftPos=i;
而(leftPos-1>=0&&blocks[leftPos-1]>=blocks[leftPos]){
leftSum++;
左位--;
}
}
int rightSum=0;
int rightPos=i;
而(rightPos+1=blocks[rightPos]){
rightSum++;
rightPos++;
}
返回rightSum+leftSum;
}
)
.max().getAsInt();
}

这个问题可以在O(n)时间内回答。你只需要改变你看待问题的方式。它真的在问你,直方图中两个相邻峰值之间的最大距离是多少

基本上,当您遍历阵列时,请记住上一个峰值。然后,对于您当前的位置,您需要标记您是要上斜坡还是要下斜坡。如果你在往下走,那么继续往下走直到你到达谷底,然后继续往上走直到你到达顶峰。然后找出此峰值和前一峰值之间的距离。最后,记住当前峰值作为前一峰值并继续

我在下面用C#编写了一个解决方案,但这应该很容易翻译成Python或您选择的语言

类解决方案
{
公共整数解算(整数[]arr)
{
//将当前高度另存为阵列的起点
var currentHeight=arr[0];
//用于保存当前最大距离的最大值
var max=0;
//我们检测到的上一个峰值的位置。从索引0开始。
var-prevPeak=0;
//阵列中的当前位置
var i=0;
//指示我们是上斜坡还是下斜坡。
var goingUp=假;
//用于保存峰值的起始位置;两个相邻的
//具有相同高度的节点可能位于峰值。
//我们想把距离作为这个序列的开始
var currentPeakStart=0;
而(i=到下一个节点或
//如果我们要向上爬坡,当前节点为=arr[i+1])| |(goingUp&&curr