栈排序&最大直方图面积 cs精英挑战营-专题训练课

前沿:
自强不息:投入,每一个环节细致。
在乎方法;及时沟通
想象力,计算机科学相对比较抽象。
根据算例,跑一些算例。实地去计算、去使用。

栈排序

栈 stack : pop 出栈 、 push 进栈 、 LIFO 后进先出

insertionsort:插入排序 O(I+n)( I(inversion):逆序对 度量序列的有序性 n:序列输入长度 )
输入敏感:算法复杂度与输入长度有关的
假设前面的(prefix)均为有序的(S,sorted),后面的(suffix)为随机的(R,random)
将后面默认无序的部分逐个插入前面的sorted中。
常规用数组向量来实现。

in-place = 就地 (即要求算法所允许使用的空间)
用栈存储输入、输出数据。算法空间复杂度为O(1)。
将S与R各自组为栈。R的栈顶为即将要插入的栈元素。O(1)说明有一个可以放外面(即要插入的元素)。
将S的栈顶元素pop到R中。直至需要插入的区域,将要插入的元素push进S栈。将原有pop出去的栈顶
S栈内始终为有序的元素。
比较S栈顶与待排序元素大小->决定挪动方向。
若 S栈顶元素小,那么待排序元素直接push进入
若 S栈顶元素大,那么比待排序元素大的全部push进R。直至出现前者情况,逐个push进入。

stacksort伪代码(栈R、S)
stack<int> S:输出的载体
int t = R.pop() ;
while ( ! R.empty() ) 
	if(  S.empty() || S.top() <= t ) # S栈顶空(思维方式:栈前有一个若有若无的很小的元素) 或者 S栈顶元素比待排序元素小
		S.push(t) ; t = R.pop();
	else
		R.push(S.pop());
	S.push(t)  #不遗漏最后一个t
return s;

利用python实现栈排序功能的详细代码请见
https://blog.csdn.net/weixin_43829465/article/details/95925876

最大直方图面积

Maximal rectangle in a histogram (可以推广到 matrix。 二者存在一个规约)
matrix 先固定底边的情况->直方图问题

思路最重要、动眼观察比动手重要。

Histogram k为某个极小值点(为上面的封顶点)
ik k jk 任意一个k均有一个左右均挡住的点(左右卡位点)。 注意左右两边默认有最小的取值哨兵。
S = H[K]*(jk - ik -1) ( -1:若jk与ik挨着的时候补上-1就能保证为零)

Bruteforce 暴力 复杂度平方量级

遍历k个极小值点。记录下每个极大值面积。再做比较

divide-conquer 分治(快速排序、归并排序)

以k点作为pivot。k点为极小值点。分这一步完成了。
治:在左边的区间和右边的区间寻找最大的矩形
merge(合并)。左右最大的矩形进行合并。
max Rect(H,lo,hi)
k = find pivot(H,lo,hi)
左边最大矩形面积 max Rect(H,lo,k) 默认左闭右开
右边最大矩形面积 max Rect(H,k+1,hi)
横贯的最大矩形面积 S = H[K]*(jk - ik -1)
取三者的最大值 返回

时间复杂度与空间复杂度
时间复杂度T(n): 最好的话两个问题 分一半 2T(n/2) 或者 最坏情况 T(n-1)
寻找极小值:遍历寻找在lo与hi的最小值 O(n) (2T(n/2)变为 nlogn T(n-1)变为n方)
可以制作一个极小值查询表(预处理) : lookup table 查询表 二维表 横坐标lo 纵坐标hi
造需要的时间O(n方),需要的储空间O(n方),询需要的时间O(1)
对区段进行查询 Min\Max\Sum 可以利用线段树进行查询 segment tree
造需要的时间O(n或nlogn),需要的储空间O(n),询需要的时间O(logn)
因此采用线段树 查询时间为logn 加上最大的时间复杂度T(n-1) 最大的空间复杂度为nlogn

引入解决这个问题
栈从底到顶会越来越大,必须是左边第一个比他矮的。
第二种情况,在右边比k点的极小值 还小。

伪代码:

maxRect(H[ ] ,n)
stack(rank) M  (暗示栈顶均是min极小值)M栈元素从栈底到栈顶逐渐增大。
int maxRect =0;
for (rank k=0 ; k < n ; ___ )
	if (M.empty() || H[M.top()] <= H[k]   )
		M.push(k++);   # 将k push进去
	else     # 找到了相应的元素	H[M[top]]*( H[ M[top-1] ] , k )
		t = M.pop();
		maxRect = max( maxRect , H[t] *(M.empty()? k ; (k-M.top()-1)) ) #注意M栈是否为empty 若是 则要单独处理 
	while( ! M.empty() )
		t = M.pop()

小结: 用栈求解最大直方图面积 空间复杂度O(n)
复杂度主要在pushpop操作上,每个元素最多进栈一次,是一个线性的算法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值