[Algorithm combat] Generate an array of window maximum values

[Algorithm combat] Generate an array of window maximum values

We have done algorithmic questions. The difficulty of the questions is divided into four levels: "Senior, Wei, School, and General". The module of this algorithm problem is the one with relatively small length. The first is to give a description of a problem, and then I will use my ideas to do this problem. Today is the first problem of the algorithm problem. Let's try the water first.

Problem description (level: Wei)

有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置。
例如,数组为[4,3,1,5,4,3,7,5],窗口大小为5时:
[4 3 1 5 4] 3 7 5  max = 5
4 [3 1 5 4 3] 7 5  max = 5
4 3 [1 5 4 3 7] 5  max = 7
4 3 1 [5 4 3 7 5]   max = 7
即窗口最大值数组为 result = {5, 5,7,7}

answer:

For a problem, I usually think of using a violent method to do it the first time, and then slowly optimize it later.

Obviously, it is quite simple to use the brute force method for this problem. Every time the window moves one place to the right, we traverse the w elements in the window each time, and then find the maximum value of the window at this time. The time complexity of this method is O(wn). code show as below:

//暴力法求解
   public static int[] getMaxWindow(int[] arr, int w) {
       if (w < 1 || arr == null || arr.length < w) {
           return null;
       }
       int[] result = new int[arr.length - w + 1];
       int index = 0;
       //暴力求解直接从第 w-1个元素开始遍历
       for (int i = w - 1; i < arr.length; i++) {
           int max = arr[i];
           //找出最大值
           for (int k = i; k > i - w; k--) {
               if (max < arr[k]) {
                   max = arr[k];
               }
           }
           result[index++] = max;
       }
       return result;
   }

Note: You can pull left and right

Everyone think about a question, for example, for the array in the example just now:

In the first traversal, max = 5

[Algorithm combat] Generate an array of window maximum values

In the second traversal, max = 5

[Algorithm combat] Generate an array of window maximum values

When we just used the brute force method, whether it was the first time or the second time, we traversed all the elements in the window once to find the maximum value, but is this really necessary?

During the first traversal, we found max = 5, so in the second traversal, within the window range, are the two numbers 1, 3 on the left of max = 5 still the maximum? In other words, is it necessary to traverse the window elements on the left of max=5?

Obviously, the window on the left of max=5 does not actually need to be traversed anymore, that is, it cannot be the maximum value of the window.

And max = 5, is the 4 on the right side the maximum value of the window? Since the window will continue to move to the right, the window element on the right of max = 5 may still be the maximum value of a certain window.

Therefore, we can use a two-way queue to record the subscript that may become the maximum value of the window. Note that it is possible here.

Like just max = 5, the 1,3 in front of it cannot be the maximum value of the window, and the 4 on the right may still be the maximum value of the window. And this queue is ordered, the head of the queue is always the maximum value in the queue,

Let me demonstrate with this question. We use the result[] array to store the maximum value of the window.

1、result[0] = 5

[Algorithm combat] Generate an array of window maximum values

2、result[1] = 5;

[Algorithm combat] Generate an array of window maximum values

3、result[2] = 7

[Algorithm combat] Generate an array of window maximum values

All the others have to be dequeued, because the 5, 4, and 3 before 7 cannot be the maximum value of the window.

4、result[3] = 7

[Algorithm combat] Generate an array of window maximum values

The traversal is complete. The time complexity of this method is O(n).

I only provide ideas and general practices here, and there are still many details that need attention in the specific code implementation. The implementation code is given below and the code will be explained in detail.

//优化
   public static int[] getMaxWindow2(int[] arr, int w) {
       if (w < 1 || arr == null || arr.length < w) {
           return null;
       }
       //用来保存成为最大窗口的元素
       int[] result = new int[arr.length - w + 1];
       int index = 0;
       //用链表从当双向队列。
       LinkedList<Integer> temp = new LinkedList<>();
       //刚才演示的时候,我i直接从i = w-1那里开始演示了。
       for (int i = 0; i < arr.length; i++) {
           //如果队列不为空,并且存放在队尾的元素小于等于当前元素,那么
           //队列的这个元素就可以弹出了,因为他不可能会是窗口最大值。
           //【当前元素】指的是窗口向右移动的时候新加入的元素。
           while (!temp.isEmpty() && arr[temp.peekLast()] <= arr[i]) {
               temp.pollLast();//把队尾元素弹出
           }
           //把【当前元素】的下边加入到队尾
           temp.addLast(i);
           //如果队首的元素不在窗口范围内,则弹出
           if (temp.peekFirst() == i - w) {
               temp.pollFirst();//
           }
           if (i >= w - 1) {
               //由于队首存放的是最大值,所以队首总是对应窗口的最大值元素
               result[index++] = arr[temp.peekFirst()];
           }
       }
       return result;
   }

To be honest, it’s a bit uncomfortable to read the code on WeChat. It’s better if you’re browsing on a computer. I’m considering whether to use screenshots, but if it’s a screenshot, some people will not be able to copy the code if they want to copy the code. Consider packaging the code, and you will reply to get it in the background.

  • End-
    Recommended reading:
    Take you step by step to learn time complexity and space complexity.
    Talk about NAT: What? What the hell are global IP and private IP?

[Algorithm combat] Generate an array of window maximum values

Guess you like

Origin blog.51cto.com/15015171/2555353