Algorithm Learning | Monotone Stack LeetCode 739. Daily Temperature, 496. Next Larger Element I

1. Theoretical knowledge

1. When to use a monotonic stack?

It is usually a one-dimensional array. To find the position of the first element on the right or left of any element that is larger or smaller than itself, we must think of using a monotone stack. Monotonic stack records traversed elements

2. What is the essence of the monotonic stack

The essence of a monotonic stack is to exchange space for time, because a stack needs to be used to record the first element on the right that is higher than the current element during the traversal process. The advantage is that the entire array only needs to be traversed once.

3. When using a monotonic stack, you must first clarify the following points

1. What are the elements stored in the monotonic stack?
The monotonic stack only needs to store the subscript i of the element. If you need to use the corresponding element, you can directly obtain it by T[i].
2. Are the elements in the monotonic stack incremented? Or is it decreasing? (The order from the top of the stack to the bottom of the stack)
If you seek the first larger element on the right of an element, the monotonic stack is increasing, and if you are seeking the first smaller element on the right of an element, the monotonic stack is decreasing.
3. There are three main judgment conditions for using a monotonic stack: the
currently traversed element T[i] is smaller than the stack top element T[st.top()] The
currently traversed element T[i] is equal to the stack top element T[st.top ()] The
current traversed element T[i] is greater than the stack top element T[st.top()]

2. Daily temperature

Please regenerate a list based on the daily temperature list. The output of the corresponding location is: if you want to observe a higher temperature, you need to wait at least the number of days. If the temperature doesn't rise after that, substitute 0 in this place.
For example, given a list temperatures = [73, 74, 75, 71, 69, 72, 76, 73], your output should be [1, 1, 4, 2, 1, 1, 0, 0].

train of thought

The monotonic stack records the traversed elements, and then compares the current traversed element with the stack port element:
1. If the currently traversed element is greater than the stack port element, record the result and pop the stack port element, continue to compare, and record the result if it is greater than the stack port element , until the current traversal element is less than the top element of the stack, add the current traversal element to the stack;
2. If the current traversal element is less than or equal to the stack head element, directly add it to the stack; in
this way, we can ensure that our stack is a monotonically increasing stack. Comparing with the element at the stack mouth for the second time, the element found must be the first element on the right that is larger than it

Implementation code

class Solution {
    
    
public:
    vector<int> dailyTemperatures(vector<int>& T) {
    
    
        stack<int> st;
        vector<int> result(T.size(), 0);
        st.push(0);
        for(int i = 1; i < T.size(); i++) {
    
    
            if(T[i] < T[st.top()]) {
    
    
                st.push(i);
            } else if(T[i] == T[st.top()]) {
    
    
                st.push(i);
            } else {
    
    
                while(!st.empty() && T[i] > T[st.top()]) {
    
    
                    result[st.top()] = i - st.top();
                    st.pop();
                }
                st.push(i);
            }
        }
        return result;   
    }
};

3. The next larger element I

You are given two arrays nums1 and nums2 with no duplicate elements, where nums1 is a subset of nums2. Please find out the next greater value of each element in nums1 in nums2. The next greater element of the number x in nums1 is the first element greater than x to the right of the corresponding position of x in nums2. If it does not exist, output -1 for the corresponding position.

train of thought

1. The size of the result array is determined by the nums1 array.
2. The monotonic stack traverses nums2. In the process of traversing nums2, we need to judge whether nums2[i] has appeared in nums1. Since there are no repeated elements, we can use map to do it map. (Quickly find the subscript according to the value, and you can also judge whether nums2[i] has appeared in nums1)

Implementation code

class Solution {
    
    
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
    
    
        stack<int> st;
        vector<int> result(nums1.size(), -1);
        if(nums1.size() == 0) return result;
    
        unordered_map<int, int> umap; // key:下标元素 value:下标
        for(int i = 0; i < nums1.size(); i++) {
    
    
            umap[nums1[i]] = i;
        }
        st.push(0);
        for(int i = 1; i < nums2.size(); i++) {
    
    
            if(nums2[i] < nums2[st.top()]) {
    
    
                st.push(i);
            } else if(nums2[i] == nums2[st.top()]) {
    
    
                st.push(i);
            } else {
    
    
                while(!st.empty() && nums2[i] > nums2[st.top()]) {
    
    
                    if(umap.count(nums2[st.top()]) > 0) {
    
     //看map中是否存在这个元素
                       int index = umap[nums2[st.top()]]; //根据map找到栈顶元素在nums1中的下标
                       result[index] = nums2[i];
                    }
                    st.pop();
                }
                st.push(i);
            }
        }
    return result;
    }
};

Guess you like

Origin blog.csdn.net/li26324949/article/details/130125894