Sunday, October 14, 2012

向后看——经典的单调栈应用

题目大意:有N个人,顺次排列,他们的身高分别为H[i],每个人向自己后方看,他能看到的人是在他后面离他最近的且比他高的人。请依次输出每个人能看到的人的编号Next[i],如果他后面不存在比他高的人,则输出-1。

显然,用两个for嵌套可以解决这个问题,不过时间复杂度是N^2级别的。

对于这道题,还存在一个复杂度N的算法。

定义一个栈S用来存放还没有确定Next的人的编号,容易证明,S从栈底到栈顶一定是单调递减(或者相等)的。从左到右扫描H数组。
  1. 如果栈空,那么Push(S,i)。 
  2. 如果当前H[i]大于栈顶元素,那么Next[S[top]]=i,Pop(S),不断执行直到栈空或者栈顶元素大于当前H[i]。然后Push(S,i)。
当扫描完所有人后,已经离开S中的人的Next就已经确定了,依然在S中的人的Next就是-1。

由于每个元素都进栈一次,至多出栈一次, 因此时间复杂度是线性级别的。

No comments:

Post a Comment