pro_gamer
pro_gamer

Reputation: 194

Finding maximum in a sliding window

The goal is to find the maximum in a sliding window in O(n) time. 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, . . . , 𝑎𝑛 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 ≤ 𝑖 ≤ 𝑛.

Output Format

Output max{𝑎𝑖, . . . , 𝑎𝑖+𝑚−1} for every 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
2 7 3 1 5 2 6 2
4

Output:

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.)

Upvotes: 2

Views: 823

Answers (2)

garima garg
garima garg

Reputation: 310

// 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.

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

Upvotes: -1

Shridhar R Kulkarni
Shridhar R Kulkarni

Reputation: 7063

Time used is 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. Your approach to the problem is optimal one but the implementation has 2 * O(n) insertions. 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.

Upvotes: 4

Related Questions