Monotonic stack of C++ data structure

definition

Monotone Stack : A special kind of stack. Based on the "first in last out" rule of the stack, it is required that "the elements from the top of the stack to the bottom of the stack are monotonically increasing (or monotonically decreasing)". Among them, the elements from the top of the stack to the bottom of the stack are monotonically increasing stacks, called "monotonically increasing stacks". The elements that meet the requirements from the top of the stack to the bottom of the stack are monotonically decreasing stacks, called "monotonically decreasing stacks".

Here, the monotonic stack is described based on the order from the top of the stack to the bottom of the stack.

1. Basics

1.1 Monotonically increasing stack

Monotonically increasing stack : Only elements smaller than the top element of the stack can be directly pushed into the stack, otherwise, the element smaller than the current element in the stack needs to be popped out first, and then the current element is pushed into the stack.

In this way, it is guaranteed that all the values ​​retained in the stack are larger than the current stacked elements, and the value of the elements from the top of the stack to the bottom of the stack is monotonically increasing.

Frequently appearing exam questions are as follows, simulating [2, 7, 5, 4, 6, 3, 4, 2]the process of pushing and popping an array in a monotonically increasing stack.

step i element to be inserted operate Result (bottom of the stack on the left) effect
1 2 2 push [2] the element to the left of element 2 that is greater than 2
2 7 2 pop, 7 push [7] The element to the left of element 7 is greater than the element 7
3 5 5 push [7, 5] The first element on the left of element 5 that is greater than 5 is: 7
4 4 4 push [7, 5, 4] The first element on the left of element 4 that is greater than 4 is: 5
5 6 4 pop, 5 pop, 6 push [7, 6] The first element on the left of element 6 that is greater than 6 is: 7
6 3 3 push [7, 6, 3] The first element on the left of element 3 that is greater than 3 is: 6
7 4 3 pop, 4 push [7, 6, 4] The first element on the left of element 4 that is greater than 4 is: 6
8 2 2 push [7, 6, 4, 2] The first element on the left of element 2 that is greater than 2 is: 4

1.2 Monotonically decreasing stack

Monotonically decreasing stack : Only elements larger than the top element of the stack can be directly pushed into the stack, otherwise, the element larger than the current element in the stack needs to be popped out of the stack first, and then the current element is pushed into the stack.

In this way, it is guaranteed that all the values ​​retained in the stack are smaller than the current stacked elements, and the element values ​​from the top of the stack to the bottom of the stack are monotonically decreasing.

Here is also [4, 3, 2, 5, 7, 4, 6, 8]an example

step i element to be inserted operate Result (bottom of the stack on the left) effect
1 4 4 push [4] The left side of element 4 is the element smaller than 4
2 3 4 pop, 3 push [3] the element to the left of element 3 that is smaller than 3
3 2 3 pop, 2 push [2] the element to the left of element 2 that is smaller than 2
4 5 5 push [2, 5] The first element to the left of element 5 that is smaller than 5 is: 2
5 7 7 push [2, 5, 7] The first element to the left of element 7 that is smaller than 7 is: 5
6 4 7 pop, 5 pop, 4 push [2, 4] The first element to the left of element 4 that is smaller than 4 is: 2
7 6 6 push [2, 4, 6] The first element to the left of element 6 that is smaller than 6 is: 4
8 8 8 push [2, 4, 6, 8] The first element to the left of element 8 that is smaller than 8 is: 6

Applicable scenarios for monotonic stacks

The monotonic stack can solve the first element on the left or right of an element that is larger or smaller than it when the time complexity is O(n).

So monotonic stacks are generally used to solve several problems:

  • Finds the first element on the left that is greater than the current element.
  • Finds the first element on the left that is smaller than the current element.
  • Finds the first element on the right that is greater than the current element.
  • Finds the first element to the right that is smaller than the current element.

The classification solution above is a bit convoluted, and can be simply recorded as the following rules:

  • Regardless of the question type, it is recommended to traverse elements from left to right.
  • To find "elements larger than the current element", use a monotonically increasing stack , and to find "elements smaller than the current element", use a monotonically decreasing stack .
  • Search from the "left side" to see the top element of the stack when "inserting the stack" , and search from the "right side" to see the element that will be inserted when "popping the stack" .

Monotonic Stack Template

monotonically increasing stack

//单调递增栈
template<typename T>
void IncStack(stack<T>& s,const vector<T> &nums) {
    
    
	for (auto it = nums.begin(); it != nums.end(); it++) {
    
    
		while (!s.empty() && s.top() <= *it) {
    
    
			s.pop();
		}
		s.push(*it);
	}
}

This template converts an array into a monotonically increasing stack.

monotonically decreasing stack

//单调递减栈
template<typename T>
void DecStack(stack<T>& s, const vector<T>& nums) {
    
    
	for (auto it = nums.begin(); it != nums.end(); it++) {
    
    
		while (!s.empty() && s.top() >= *it) {
    
    
			s.pop();
		}
		s.push(*it);
	}
}

The old rules are useful Erlian, thank you everyone!

Guess you like

Origin blog.csdn.net/suren_jun/article/details/127446815