【Lintcode】751. John‘s Business

Subject address:

https://www.lintcode.com/problem/johns-business/description

Given a length nnn arrayAAA , and then give a non-negative integerkkk , request to return an arrayBBB,使得 B [ i ] = A [ i ] − min ⁡ A [ i − k : i + k ] B[i]=A[i]-\min A[i-k:i+k] B[i]=A[i]minA[ik:i+k]

Monotonic queues can be used. Open a monotonously ascending queue, maintain the head of the queue to be the minimum value of the current query interval, and increase monotonically from the head to the end of the queue. When traversing to A [i] A[i]When A [ i ] , then the query interval isA [i − k: i + k] A[ik:i+k]A[ik:i+k ] , we considerA [i + k] A[i+k]A[i+k ] is the query interval of the right end. First, the number of the query interval (ieA [i − k − 1] A[ik-1]A[ik1 ] ) Depart from the team, and then it is easy to know,A [i + k] A[i+k]A[i+k ] can PK down all the numbers whose tail is greater than or equal to it. The reason is thatA [i + k] A[i+k]A[i+In the query interval where k ] and all the numbers on the right are the right end points, a number greater than or equal to it cannot be the minimum value of the query interval. We can use mathematical induction to prove that under the above PK process, the queue always rises monotonically, and the head of the queue is always the minimum value of the query interval with the current end of the line as the right end (the monotonic rise property is easy to prove, as for why the head of the line always The minimum value, the head of the team that has been kicked out of the window first, and the head of the team that has not been out of the window, first, the number of positions in the window to the left of the head of the team must be greater than or equal to it, because they are the head of the current team or greater than or equal to it The number PK of the current team leader has dropped, and the number on the right of the current team leader must be greater than or equal to it, otherwise they should be able to PK off the current team leader. So the current team leader is the minimum value of the current query interval). In this question, you can first traverseA [0: k − 1] A[0:k-1]A[0:k1 ] , get a monotonic queue, and then re-traverseA [0: n − 1] A[0:n-1]A[0:n1 ] (Essentially at the center of the enumeration). When traversing a number, first kick the number out of the window on its left, and then enqueue it as the right end of the center and maintain monotonicity, so that the current The minimum value of the query interval centered on the number is the head of the line. code show as below:

import java.util.ArrayDeque;
import java.util.Deque;

public class Solution {
    
    
    /**
     * @param A: The prices [i]
     * @param k:
     * @return: The ans array
     */
    public int[] business(int[] A, int k) {
    
    
        // Write your code here
        Deque<Integer> deque = new ArrayDeque<>();
        for (int i = 0; i < Math.min(k, A.length); i++) {
    
    
            while (!deque.isEmpty() && A[deque.peekLast()] >= A[i]) {
    
    
                deque.pollLast();
            }
            deque.offerLast(i);
        }
        
        int[] res = new int[A.length];
        // 进行枚举,i是中心点,idx是res的下标,r是i为中心点的时候的区间右端点
        for (int i = 0, idx = 0, r = k; i < A.length; i++) {
    
    
        	// 踢掉左边出了窗口的数
            if (deque.peekFirst() < i - k) {
    
    
                deque.pollFirst();
            }
            
            // 将右端点入队
            if (r < A.length) {
    
    
                while (!deque.isEmpty() && A[deque.peekLast()] >= A[r]) {
    
    
                    deque.pollLast();
                }
                deque.offerLast(r);
                r++;
            }
            
            // 存一下A[i]和以i为中心点的查询区间的最小值的差
            res[idx++] = A[i] - A[deque.peekFirst()];
        }
        
        return res;
    }
}

Time and space complexity O (n) O(n)O ( n )

Guess you like

Origin blog.csdn.net/qq_46105170/article/details/114122222