首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >寻找最大的连续间隔,这样从开始到结束之间的所有数都大于开始,小于结束。

寻找最大的连续间隔,这样从开始到结束之间的所有数都大于开始,小于结束。
EN

Stack Overflow用户
提问于 2020-09-22 05:49:42
回答 2查看 398关注 0票数 3

你已经给出了整数数组

例如5,3,4,3,9,4,4,6,6,5,7

你必须找出最大区间(i,j),使i和j之间的所有数在i处大于等于数,而在J处小于数。数字不必按顺序排列。我的数字也应该小于j的数。

在上面的例子中,有两个这样的间隔: 3,4,3,9和4,4,6,8

在3,4,3,9 -中间两个数字(4,3)大于等于起始数(3),但小于等于结束数(9)。启动数(3)也小于结束数(9)。

在4,4,6,8 -中间两个数字(4,6)大于等于起始数(4),但小于等于结束数(8)。启动数(4)也小于结束数(8)。

解决这个问题的一种方法是检查大小n的所有区间,然后再检查n-1,直到得到这样的区间为止。但我想要的是高效的分而治之,或征服/DP/或其他方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-22 17:29:26

我们可以在O(n log n)中通过将每个元素看作区间中最左边的潜在元素来解决这个问题。对于每个这样的候选元素,(1)在右侧找到低于它的第一个元素--这是可能间隔的右边的一个界,因为包含这样的元素将使约束失效;(2)在区间中找到最大值元素的最左边的实例(或者最右边的元素,如果允许A[j]等于它左边的一个元素)--这是间隔可以扩展的最右边而不使约束无效。

我们可以使用堆栈存储O(n)中所有元素的(1)答案。我们可以预处理一个范围最大查询的结构,该结构将在O(log n)时间内回答(2)的第一部分。一旦找到了间隔的最大值,如果数组中有其实例的有序列表(我们可以用哈希表在O(n)中进行预处理),我们就可以在O(log n)时间间隔中找到最右边或最左边的实例。

票数 3
EN

Stack Overflow用户

发布于 2020-09-22 08:15:58

DP给出了一个简单的答案,希望它能帮到你:

代码语言:javascript
复制
public class Test {

    public static void main(String[] args){

        int[] input = {5,3,4,3,9,4,4,6,8,6,5,7};

        //
        // lenDp array to store the max possible interval sizes starting at every index.
        //
        int[] lenDp = new int[input.length];
        //
        // minNumIdxs array to store the indexes of minimum numbers in all sub arrays with the same length
        //
        int[] minNumIdxs = new int[input.length];

        //
        // for a start, every number is an interval with size of 1,
        // and there are as many sub arrays with length of 1 as input.length,
        // the minimum number in a sub array is the first number:
        //
        for(int i = 0; i < input.length; i++){
            lenDp[i] = 1;
            minNumIdxs[i] = i;
        }

        int maxLen = 1;

        //
        // check all possible intervals of size from 2 to input.length
        //
        for(int len = 2; len <= input.length; len++){
            //
            // for every possible interval with size of `len`, the starting index can be in range of [0, input.length - len]
            //
            for(int i = 0, end = input.length - len; i <= end ; i++ ){

                //
                // assume the interval of size `len` is possible for index i,then the number at input[i] has to be the minimum number,
                // and the number at input[i + len - 1] has to be greater than or equal to
                // the largest number ( at input[i + dp[i] - 1] ) of the current interval starting at index i.
                // in the corner case where dp[i] == 1 and len > 2, it wouldn't be valid, for example:
                // when len = 5, i = 0, dp[i] = dp[0] = 1, then input[i + len - 1] = input[0 + 5 - 1] = input[4] = 9;
                // 9 is greater than 5 (input[0]), but it's invalid.
                // So we also need to check (len == 2 || dp[i] > 1)
                //
                if(minNumIdxs[i] == i && input[i + len - 1] >= input[i + lenDp[i] - 1] &&
                        (len == 2 || lenDp[i] > 1)){
                    lenDp[i] = len;
                    maxLen = len;
                }

                //
                // update the index of the minimum number in the sub array starting at i
                //
                if(input[i + len - 1] < input[minNumIdxs[i]])minNumIdxs[i] = i + len - 1;
            }
        }



        //
        // print out the final result
        //
        for(int i = 0 ; i < lenDp.length ; i++){
            if(lenDp[i] == maxLen){
                System.out.println(Arrays.toString(Arrays.copyOfRange(input, i, i + maxLen)));
            }
        }

    }

}

产出:

代码语言:javascript
复制
 [3, 4, 3, 9]
 [4, 4, 6, 8]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64003751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档