在滑动窗口中找到最大值

时间:2019-08-25 07:05:08

标签: java algorithm time-complexity

目标是在O(n)时间内在滑动窗口中找到最大值。我已经使用队列双端队列实现了此操作,但是我无法满足时间限制,因此需要优化我的解决方案。

输入格式

第一行包含一个整数?,第二行包含一个整数?1,。 。 。 ,??用空格分隔,第三行包含整数?。

约束

1≤?≤10等于5的幂,1≤?≤?,0≤??≤10等于1≤?≤all的5的幂。

输出格式

最大输出{??,。 。 。 ,??+ ?−1}每1≤?≤?-?+ 1。

代码

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());
    }

}
}

`

样本输入

输入:

  

8
2 7 3 1 5 2 6 2
4

输出:

  

7 7 5 6 6

错误

此代码在输入大小为100000时失败。 失败的案例#160/198:超过了时间限制 (已使用时间:1.61 / 1.50,已使用内存:85409792/536870912。)

2 个答案:

答案 0 :(得分:3)

使用时间为1.61 / 1.50。所以你足够亲近了。

由于要插入队列以及ArrayDequeue,所以时间限制略有超出。解决该问题的方法是最佳的,但是该实现具有2 * O(n)个插入。简化代码以仅使用出队数据结构。确保不要在任何数据结构中存储在滑动窗口中找到的最大值,而直接将其输出。这应该使您的解决方案被接受。让我们知道是否可行。

答案 1 :(得分:-1)

//请根据您的要求修改输入格式

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);
}

//获得窗口大小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;
}

//打印数组元素的简单显示方法

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