简体   繁体   English

在滑动窗口中寻找最大值

[英]Finding maximum in a sliding window

The goal is to find the maximum in a sliding window in O(n) time.目标是在 O(n) 时间内找到滑动窗口中的最大值。 I have implemented this using queue deque, but I am not able to satisfy the time constraints and hence need to optimize my solution.我已经使用队列双端队列实现了这一点,但我无法满足时间限制,因此需要优化我的解决方案。

Input Format输入格式

The first line contains an integer 𝑛, the second line contains 𝑛 integers 𝑎1, .第一行包含一个整数 𝑛,第二行包含 𝑛 整数 𝑎1, 。 . . . . , 𝑎𝑛 separated by spaces, the third line contains an integer 𝑚. , 𝑎𝑛 以空格分隔,第三行包含一个整数𝑚。

Constraints约束

1 ≤ 𝑛 ≤ 10 to the power of 5, 1 ≤ 𝑚 ≤ 𝑛, 0 ≤ 𝑎𝑖 ≤ 10 to the power of 5 for all 1 ≤ 𝑖 ≤ 𝑛. 1 ≤ 𝑛 ≤ 10 的 5 次方,1 ≤ 𝑚 ≤ 𝑛,0 ≤ 𝑎𝑖 ≤ 10 的 5 次方,对于所有 1 ≤ 𝑖 ≤ 𝑛。

Output Format输出格式

Output max{𝑎𝑖, .输出最大值{𝑎𝑖, . . . . . , 𝑎𝑖+𝑚−1} for every 1 ≤ 𝑖 ≤ 𝑛 − 𝑚 + 1. , 𝑎𝑖+𝑚−1} 对于每 1 ≤ 𝑖 ≤ 𝑛 − 𝑚 + 1。

Code代码

public class MaxSlidingWindow_ {

public static void push(Queue<Integer> q, ArrayDeque<Integer> dq, int value) {
    q.add(value);
    if (dq.isEmpty()) {
        dq.add(value);
    } else {
        while (dq.peekLast() < value) {
            dq.pollLast();
            if (dq.isEmpty())
                break;
        }
        dq.addLast(value);
    }
}

public static void pop(Queue<Integer> q, ArrayDeque<Integer> dq) {
    int qval = q.remove();
    if (qval == dq.peekFirst()) {
        dq.remove();
    }
}

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    scanner.nextLine();
    int[] elements_stack = new int[n];
    for (int i = 0; i < n; i++) {
        int temp = scanner.nextInt();
        elements_stack[i] = temp;
    }
    scanner.nextLine();
    int m = scanner.nextInt();

    Queue<Integer> q = new LinkedList<Integer>();
    ArrayDeque<Integer> dq = new ArrayDeque<Integer>();

    for (int i = 0; i < m; i++) {
        int val = elements_stack[i];
        push(q, dq, val);
    }
    System.out.print(dq.peek());
    for (int i = m; i < n; i++) {
        int val = elements_stack[i];
        pop(q, dq);
        push(q, dq, val);

        System.out.print(" " + dq.peek());
    }

}
}

` `

Sample Input样本输入

Input:输入:

8 8
2 7 3 1 5 2 6 2 2 7 3 1 5 2 6 2
4 4

Output:输出:

7 7 5 6 6 7 7 5 6 6

Error错误

This code fails for input size of 100000. Failed case #160/198: time limit exceeded (Time used: 1.61/1.50, memory used: 85409792/536870912.)此代码在输入大小为 100000 时失败。失败案例 #160/198:超出时间限制(使用时间:1.61/1.50,使用的内存:85409792/536870912。)

Time used is 1.61/1.50.使用时间为 1.61/1.50。 So you are close enough.所以你已经足够接近了。

The time limit is exceeding by a slight margin because you are inserting in queue as well as ArrayDequeue.由于您正在插入队列以及 ArrayDequeue,因此时间限制略有超出。 Your approach to the problem is optimal one but the implementation has 2 * O(n) insertions.您解决问题的方法是最佳方法,但实现有 2 * O(n) 次插入。 Simplify your code to use just a dequeue data structure.简化您的代码以仅使用出列数据结构。 Ensure that you don't store the maximum found in the sliding window in any data structure, just output it directly.确保您没有将滑动窗口中找到的最大值存储在任何数据结构中,直接输出即可。 This should get your solution accepted.这应该让您的解决方案被接受。 Do let us know if that worked.请让我们知道这是否有效。

// Please modify the input format as per your requirement // 请根据您的要求修改输入格式

public static void main(String[] args) {
    int[] arr={1,3,-1,-3,5,3,6, 7};
int winSize=3;
long startTime=System.currentTimeMillis();
int[] arrMax=getMax(arr,winSize);
long endTime=System.currentTimeMillis();
System.out.println("*****************************************");

display(arrMax);
    System.out.println(endTime-startTime);
}

// get Maximum of the elements in window size B. // 获取窗口大小 B 中元素的最大值。

private static int[] getMax(int[] A,int B){
List<Integer> list=new ArrayList<>();
    int[] tempA=new int[B];
            for(int i=0;i<A.length-B+1;i++){
                tempA=Arrays.copyOfRange(A, i, i+B);
                Arrays.sort(tempA);
                list.add(tempA[tempA.length-1]);
    }
    int[] array = list.stream().mapToInt(i->i).toArray();
    return array;
}

// Simple display method to print array elements // 打印数组元素的简单显示方法

private static void display(int[] arr){
    for (int i=0;i<arr.length;i++){
        System.out.print(" "+arr[i]);
    }
    System.out.println("");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM