单调栈的简单分享

单调栈: 一种栈的数据结构,根据栈顶到栈底的数据排序顺序,分为单调递增栈和单调递减栈。

  • 单调递增栈:从栈顶到栈底,依次递增
  • 单调递减栈:从栈顶到栈底,依次减小

以单调递增栈为例,数组arr = []{10,3,7,4,12},从左往右依次入栈
1.开始时,栈空,10入栈,栈中元素10
2.遍历到3,因为3比10小,符合递增栈,入栈,此时栈中元素为10,3
3.遍历到7入栈,由于栈顶元素3小于7,元素3出栈,7比10小,入栈,此时栈中元素为10,7
4.4入栈,小于栈顶元素,入栈,栈中元素10,7,4
5.12入栈,由于栈内元素都小于12,依次出栈,最后12入栈,此时栈中元素12
最后,该单调栈即为[]{12}

单调栈的一般思路:
stack<int> st;
//此处一般需要给数组最后添加结束标志符,具体下面例题会有详细讲解
for (遍历这个数组)
{
	if (栈空 || 栈顶元素大于等于当前比较元素)
	{
		入栈;
	}
	else
	{
		while (栈不为空 && 栈顶元素小于当前元素)
		{
			栈顶元素出栈;
			更新结果;
		}
		当前数据入栈;
	}
}
golang代码实现
package main

import "fmt"

/*
单调栈: 一种栈的数据结构,根据栈顶到栈底的数据排序顺序,分为单调递增栈和单调递减栈。
单调递增栈:从栈顶到栈底,依次递增
单调递减栈:从栈顶到栈底,依次减小

以单调递增栈为例,数组arr = []{10,3,7,4,12},从左往右依次入栈
1.开始时,栈空,10入栈,栈中元素10
2.遍历到3,因为3比10小,符合递增栈,入栈,此时栈中元素为10,3
3.遍历到7入栈,由于栈顶元素3小于7,元素3出栈,7比10小,入栈,此时栈中元素为10,7
4.4入栈,小于栈顶元素,入栈,栈中元素10,7,4
5.12入栈,由于栈内元素都小于12,依次出栈,最后12入栈,此时栈中元素12
最后,该单调栈即为[]{12}
*/

func main()  {
	arr := []int{10,3,7,4,12,10}
	fmt.Println(incrStack(arr))
	fmt.Println(decrStack(arr))
}

// 单调递增栈
func incrStack(arr []int) []int {
	stack := []int{}
	// 遍历数组
	for i:=0;i<len(arr);i++ {
		// 如果栈空或者栈顶元素大于当前元素,入栈
		if len(stack) == 0 || stack[len(stack)-1] > arr[i] {
			stack = append(stack, arr[i])
		} else { // 当栈非空且栈顶元素小于等于当前元素时,出栈
			for len(stack) > 0 && stack[len(stack)-1] <= arr[i] {
				stack = stack[:len(stack)-1]
			}
			// 出栈直到栈空或者栈顶元素大于当前元素,入栈当前元素
			stack = append(stack, arr[i])
		}
	}
	// 返回单调递增栈
	return stack
}

// 单调递增栈
func decrStack(arr []int) []int {
	stack := []int{}
	for i:=0;i<len(arr);i++ {
		// 如果栈空或者栈顶元素小于当前元素,入栈
		if len(stack) == 0 || stack[len(stack)-1] < arr[i] {
			stack = append(stack, arr[i])
		} else { // 当栈非空且栈顶元素大于等于当前元素时,出栈
			for len(stack) > 0 && stack[len(stack)-1] >= arr[i] {
				stack = stack[:len(stack)-1]
			}
			// 出栈直到栈空或者栈顶元素小于当前元素,入栈当前元素
			stack = append(stack, arr[i])
		}
	}
	return stack
}

posted on 2022-04-22 11:18  进击的davis  阅读(110)  评论(0编辑  收藏  举报

导航