find max value(when right - left + 1 == k), do n times
classSolution {publicint[] maxSlidingWindow(int[] nums,int k) {if (k ==1) {return nums; }int result[] =newint[nums.length- k +1];int left =0;for (int right =0; right <nums.length; right++) {if (right - left +1== k) {int max =Integer.MIN_VALUE; // in size k window find local maxfor (int i = left; i <= right; i++) { max =Math.max(max, nums[i]); } result[left++] = max; } }return result; }}
or left don't move, right move, also T: O(nk)
classSolution {publicint[] maxSlidingWindow(int[] nums,int k) {int n =nums.length;int[] res =newint[n-k+1];int max =Integer.MIN_VALUE;int i =0;while (i < n-k+1) {for (int j = i; j < n; j++) { max =Math.max(max, nums[j]);if (j - i +1== k) { res[i] = max; max =Integer.MIN_VALUE; i++;break; } } }return res; }}/*naive: int res[n-k+1][1 3 -1] -3 5 3 6 7 i j if (j-i == k) for (int i < j) { find max save in res, res[i] = max i++ }*/
i 0 1 2 3, i = 3, 3-3+1 = 1, so ๅฐๆผ 1 ็ index ้ฝไธๆ
new coming value is bigger than peekLast() (last roud latest), discard last,
(ๅ ็บๆฐ็้ฝๅ ๅจๅฐพ็ซฏ, ๅฆๆๆฐไพๅพๅผๆฏlastๅคง, discard last in dq
offer new coming value index (offer: offerLast()
add result
classSolution {publicint[] maxSlidingWindow(int[] nums,int k) {int n =nums.length;if (n ==0) return nums;int result[] =newint[n-k+1];Deque<Integer> dq =newArrayDeque<>();for (int i =0; i < n ; i++) {if (!dq.isEmpty() &&dq.peek() < (i - k +1)) {dq.poll(); }while (!dq.isEmpty() && nums[dq.peekLast()] < nums[i]) {dq.pollLast(); }dq.offer(i);if ((i - k +1) >=0) { // i - k + 1 ไนๅพ>=0 ๆ้ๅงๆ็ญๆก result[i - k +1] = nums[dq.peek()]; } }return result; }}
O(n)
[1, 3, - 1], 3, .....
idx = 2,
2 -3 +1 = 0, ้ๆๅๆๅบ็พ็ฌฌไธ็ต็ญๆก
if ((i - k +1) >=0) { // i - k + 1 ไนๅพ>=0 ๆ้ๅงๆ็ญๆก result[i - k +1] = nums[dq.peek()]; }
dequeue new version
T:O(n), while loop < n, so can ignore
S: O(n), since O(nโk+1) is used for an output array and O(k) for a deque.
classSolution {publicint[] maxSlidingWindow(int[] nums,int k) {int[] res =newint[nums.length- k +1];Deque<Integer> queue =newArrayDeque<>(); //dequeue stores indexfor (int i =0; i <nums.length; i++) {// so the queue will be a decresing mono queue, // we abandon smaller one in queue, remain larger one in queuewhile (!queue.isEmpty() && nums[queue.peekLast()] <= nums[i]) { queue.pollLast(); }queue.offer(i); // add data// in here, !queue.isEmpty() ไธ้่ฆ, ๅ ็บๅทฒ็ถๅ ๅ ่ณๆไบ(queue.offer(i)// if first index is out of windows, pop itif (i - k +1>queue.peekFirst()) { queue.pollFirst(); }if (i - k +1>=0) { // when i - k + 1 >= 0, start to collect result res[i - k +1] = nums[queue.peekFirst()]; } }return res; }}/*T:O(n), while loop < n, so can ignoreS: O(N), since O(Nโk+1) is used for an output array and O(k) for a deque.maintain a mono deque, qeueu first is always the max [ ] [ ]0[7,2,4] 1 2 i >= k-1 = 1 record index 7[0] if (!queue.isEmpty && nums[queue.peekLast] < nums[i]) queue.pollLast add nums[i] to queue, queue.offer(nums[i]) i - k >= quueue.peekFirst i - k + 1 == 0 add result(nums[quueue.peekFirst])*/
if 3 poll first, it's wrong, this max can remain for next to use,
unless , this time we poll the number is the max one, abandon it
more structure way
and offer number, not index
classSolution {classMonoQueue {privateDeque<Integer> deque =newArrayDeque<>();publicvoidoffer(int num) { // remain max at last, first is maxwhile (!deque.isEmpty() &&deque.getLast() < num) {deque.pollLast(); }deque.offerLast(num); }// why check max == poll num?// if num we want to poll is not the max one, it doesn't matter, so // don't poll the max// remain max for next to seepublicvoidpoll(int num) { // out of window, poll max, first if (deque.getFirst() == num) { // check first is num? true, poll itdeque.pollFirst(); } }publicintgetMax() { // max always in first positionreturndeque.getFirst(); } }publicint[] maxSlidingWindow(int[] nums,int k) {MonoQueue window =newMonoQueue();int[] result =newint[nums.length- k +1];int index =0;for (int i =0; i <nums.length; i++) {window.offer(nums[i]);if (i >= k-1) { // in i = 2 (k = 3) result[index] =window.getMax(); index++;window.poll(nums[i - k +1]); // in i == 2, pollfirst nums[0] } }return result; }}/* 0 1 k-1[1 3 -1] -3 5 3 6 7 */
```javaclassSolution {classMonoQueue {Deque<Integer> deque =newArrayDeque<>();/* [1 3 -1] -3 5 3 6 7 ๅคง -> ๅฐ mono queue k = 3 -> [1 3 -1] -3 5 3 6 7 x max Q: 3 -1 max = 3 abadon left -> 1 has abadoned */publicvoidoffer(int num) {// ๆณจๆๅ้ขๆๆฏ่ผๅฐ็ๅฐฑไธ็ดๆๆๅ๏ผwhile (!deque.isEmpty() && num >deque.getLast()) {deque.pollLast(); }deque.offer(num); }publicvoidpoll(int num) {if (deque.getFirst() == num) {System.out.println("poll"+ num);deque.pollFirst(); } }publicintgetMax() {returndeque.getFirst(); } }/* [1 3 -1] -3 5 3 6 7 x ๅคง -> ๅฐ ๏ผฑ 7 6 5 index 0 -> 7 find 7 in Queue -> max -> remove if we don't remove, this max 7 will remain because getMax -> always quque first place 7 6 5 4 3 2 1 x. b x b (abandon, if this num is max one) x b */publicint[] maxSlidingWindow(int[] nums,int k) {// how to solve find max?// use mono queueMonoQueue window =newMonoQueue();int n =nums.length;int index =0;int[] result =newint[n - k +1];for (int i =0; i < n; i++) {window.offer(nums[i]);if (i - k +1>=0) { result[index++] =window.getMax();window.poll(nums[i - k +1]); // when idx = 2 - 3 + 1 = 0, sliding window abandon left } }return result; }/* T: O(n), push num, pop num -> n times S: O(k), ksize mono queue */}```