Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 密码挑战:计算左右交替的递增序列_Algorithm_Linear Algebra - Fatal编程技术网

Algorithm 密码挑战:计算左右交替的递增序列

Algorithm 密码挑战:计算左右交替的递增序列,algorithm,linear-algebra,Algorithm,Linear Algebra,我一直在为这个编码挑战而奋斗: (基本问题是:给定一个整数列表,计算可能的升序数,如果序列的起始点在索引处,i,则序列中没有两个相邻元素(前两个除外)位于i的同一侧。例如,给定[6,2,3,4],从2开始,我们可以进入[2]、[2,3]、[2,4],[2,6],[2,3,6]或[2,4,6]。) 到目前为止,我只能考虑时间复杂度为O(N^2)的解决方案,而O(N*log(N))是必需的。尽管有人在GitHub上发布了一个解决方案,但我不知道发生了什么: 看起来他在来回做仿射变换,但我不明白为什

我一直在为这个编码挑战而奋斗:

(基本问题是:给定一个整数列表,计算可能的升序数,如果序列的起始点在索引处,
i
,则序列中没有两个相邻元素(前两个除外)位于
i
的同一侧。例如,给定[6,2,3,4],从2开始,我们可以进入[2]、[2,3]、[2,4],[2,6],[2,3,6]或[2,4,6]。)

到目前为止,我只能考虑时间复杂度为O(N^2)的解决方案,而O(N*log(N))是必需的。尽管有人在GitHub上发布了一个解决方案,但我不知道发生了什么:

看起来他在来回做仿射变换,但我不明白为什么会这样,为什么可以用O(N*Log(N))时间复杂度来实现。我希望有人能给我点启示

我在下面发布了我自己的解决方案(Java):

final class铬{
最终长模量=100000007L;
静态类嵌套实现了可比较的{
嵌套(整数索引,整数高度){
这个指数=指数;
高度=高度;
}
整数指数;
内部高度;
公共int比较(Nest nest2){
返回整数.compare(height,nest2.height);
}
}
/**
*根据连续嵌套运行的乘法计算可能性
*鸟巢的左右对焦。
*/
私有长getPossibleWays(Nest[]Orderedness,int startIndex){
Nest startNest=orderedNests[startIndex];
长途跋涉=0;
长对立面numberofways=0;
布尔值previousLeft=false;
布尔值优先=真;
int runLength=0;
对于(int i=orderedNests.length-1;i>startIndex;--i){
嵌套n=有序嵌套[i];
布尔左=n.index
通过阅读数据结构,我想我现在已经理解了,尤其是

然而,首先要对这个问题有很多见解:

准备:

  • 按巢高分类很方便。完成此操作后,高度本身并不相关,仅与嵌套数组中的位置相关。(即,所有高度将标准化为递增整数0,1,2,3,4…)。这意味着一旦对巢穴进行了分类,我们就可以忘记它们的实际高度
  • 跟踪原始数组中嵌套的索引,因为这是确定其他嵌套相对于它的相对左/右位置所必需的。在上面的图像中,索引以红色显示,高度以黑色显示
现在,确定有效方式总数的总体策略是:


  • 计算任何嵌套的方式数(k)(0 k该方式的起始嵌套有一个索引j,其中kfinal class Chromium { final long MODULUS = 1000000007L; static class Nest implements Comparable<Nest> { Nest(int index, int height) { this.index = index; this.height = height; } int index; int height; public int compareTo(Nest nest2) { return Integer.compare(height, nest2.height); } } /** * Calculates the possibilities based on the fact that it is a multiplication of the runs of consecutive nests * left and right of the nest in focus. */ private long getPossibleWays(Nest[] orderedNests, int startIndex) { Nest startNest = orderedNests[startIndex]; long ways = 0; long oppositeNumberOfWays = 0; boolean previousLeft = false; boolean first = true; int runLength = 0; for (int i = orderedNests.length - 1; i > startIndex; --i) { Nest n = orderedNests[i]; boolean left = n.index < startNest.index; if (left != previousLeft && !first) { ways += (runLength * (oppositeNumberOfWays + 1)) % MODULUS; long w = oppositeNumberOfWays; oppositeNumberOfWays = ways; ways = w; runLength = 1; } else { runLength++; } first = false; previousLeft = left; } ways += (runLength * (oppositeNumberOfWays + 1)) % MODULUS; return 1 + ways + oppositeNumberOfWays; } public int solution(int[] H) { Nest[] nests = new Nest[H.length]; for (int i = 0; i < H.length; ++i) { nests[i] = new Nest(i, H[i]); } // Sort the nests by height Arrays.sort(nests); long possibleWays = 0; for (int i = 0; i < nests.length; ++i) { possibleWays += getPossibleWays(nests, i); possibleWays = possibleWays % MODULUS; } return (int) possibleWays; } }
    def solution(H):
        MOD = 1000000007
        N = len(H)
        nests = [(height, index) for index, height in enumerate(H)]
        nests.sort()
        dp_left = [0] * N
        dp_right = [0] * N
        total = 0
    
        for nest in nests:
            index = nest[1]
    
            # Add 1 way for the current nest
            total += 1
    
            # Add all possible ways reaching this nest from the left
            for i in range(index):
                total += dp_left[i]
                total %= MOD
    
            # Add all possible ways reaching this nest from the right
            for i in range(index + 1, N):
                total += dp_right[i]
                total %= MOD
    
            # Initialize left and right ways to 1 for the current nest
            dp_right[index] = 1
            dp_left[index] = 1
    
            # Update the right possible ways for nests to the left
            for i in range(index):
                dp_right[i] += dp_left[i]
                dp_right[i] %= MOD
    
            # Update the left possible ways for nests to the right
            for i in range(index + 1, N):
                dp_left[i] += dp_right[i]
                dp_left[i] %= MOD
    
        return total % MOD