forked from rampatra/Algorithms-and-Data-Structures-in-Java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMaxInAllSubArrays.java
102 lines (89 loc) · 3.3 KB
/
MaxInAllSubArrays.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.rampatra.arrays;
import com.rampatra.base.MaxHeap;
import java.util.ArrayDeque;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
* @author rampatra
* @since 9/3/15
* @time: 9:21 PM
*/
public class MaxInAllSubArrays {
/**
* Naive approach.
* <p/>
* Finds the maximum element in each and every sub-array
* in {@param a} of size {@param k}.
* <p/>
* Time complexity: O(n*k), or more precisely O((n-k) * k)
*
* @param a
* @param k
*/
public static int[] maxInAllSubArraysOfSizeKNaive(int[] a, int k) {
int[] maxElements = new int[a.length - k + 1];
int[] kElements;
for (int i = 0; i <= a.length - k; i++) {
kElements = Arrays.copyOfRange(a, i, i + k);
/**
* maxHeapify() can't be used because to call maxHeapify() on i because left(i) and right (i) should
* already satisfy the max heap property which isn't true in this case.
*/
MaxHeap maxHeap = new MaxHeap(kElements);
maxHeap.buildMaxHeap();
maxElements[i] = maxHeap.findMax();
}
return maxElements;
}
/**
* Finds the maximum element in each and every sub-array
* in {@param a} of size {@param k}.
* <p>
* Time complexity: O(n)
* Auxiliary Space: O(k)
*
* @param a
* @param k
* @return
*/
public static int[] maxInAllSubArraysOfSizeK(int[] a, int k) {
int i, j = 0;
int[] result = new int[a.length - k + 1];
/**
* Create a Double Ended Queue, Qi that will store indexes of array elements
* The queue will store indexes of useful elements in every window and it will
* maintain decreasing order of values from front to rear in Qi, i.e,
* arr[Qi.front[]] to arr[Qi.rear()] are sorted in decreasing order.
*/
ArrayDeque<Integer> deque = new ArrayDeque<>();
for (i = 0; i < k; i++) {
// remove smaller elements on left side of current element
while (!deque.isEmpty() && a[i] > a[deque.peekLast()]) {
deque.removeLast();
}
deque.addLast(i);
}
for (; i < a.length; i++) {
result[j++] = a[deque.peekFirst()];
// remove elements that are outside window k
while (!deque.isEmpty() && deque.peekFirst() <= i - k) {
deque.removeFirst();
}
// remove smaller elements on left side of current element
while (!deque.isEmpty() && a[i] > a[deque.peekLast()]) {
deque.removeLast();
}
deque.addLast(i);
}
// for max in last k elements
result[j] = a[deque.peekFirst()];
return result;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(maxInAllSubArraysOfSizeKNaive(new int[]{1, 2, 3, 1, 4, 5, 2, 3, 6}, 3)));
System.out.println(Arrays.toString(maxInAllSubArraysOfSizeKNaive(new int[]{8, 5, 10, 7, 9, 4, 15, 12, 90, 13}, 4)));
System.out.println(Arrays.toString(maxInAllSubArraysOfSizeK(new int[]{1, 2, 3, 1, 4, 5, 2, 3, 6}, 3)));
System.out.println(Arrays.toString(maxInAllSubArraysOfSizeK(new int[]{8, 5, 10, 7, 9, 4, 15, 12, 90, 13}, 4)));
}
}