Reputation: 194
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.
The first line contains an integer 𝑛, the second line contains 𝑛 integers 𝑎1, . . . , 𝑎𝑛 separated by spaces, the third line contains an integer 𝑚.
1 ≤ 𝑛 ≤ 10 to the power of 5, 1 ≤ 𝑚 ≤ 𝑛, 0 ≤ 𝑎𝑖 ≤ 10 to the power of 5 for all 1 ≤ 𝑖 ≤ 𝑛.
Output max{𝑎𝑖, . . . , 𝑎𝑖+𝑚−1} for every 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());
}
}
}
`
Input:
8
2 7 3 1 5 2 6 2
4
Output:
7 7 5 6 6
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
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
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