寻找最近的小于当前数的位置

来源:互联网 发布:lol登录失败检查网络 编辑:程序博客网 时间:2024/05/22 04:34

这是百度一面的时候遇到的一个面试题,当然这个肯定不是原题,只是问题分解之后的一个抽象而已,当时分析复杂度的时候,说了O(n),但是没给出证明,被鄙视了。

 

1.问题:寻找最近的小于当前数的位置

给定一个数组arr[0..N-1],对于任意arr[i],求最大的j,满足j<i且arr[j]<arr[i],也就是最近的小于当前数的位置。如数组 [ 8, 9, 4, 5, 7, 6, 4 ],当i=5,时j=3

(arr[i] = 6, arr[j] = 5)

 

解决思路就是动态规划,用dp[i]代表arr[i]对应的j的位置

 

因为用公式比较难描述状态转移,我直接用文字进行。

首先dp[0] = -1,这个比较特别,随意即可,可以认为-1表示不存在

 

在计算dp[i]的时候,dp[0..i-1]已经全部计算好了,那么分两种情况来计算dp[i]:

如果arr[i]>arr[i-1],那么dp[i] = i-1;

如果arr[i]<=arr[i-1],那么,可以肯定数组中,半开区间( dp[i-1], i-1 ] 对应的数组元素的值肯定比都>=arr[i],{ 令k=dp[i-1],判断arr[i]与arr[k]的大小关系,如果arr[i]>arr[k],则dp[i]=k,否则k = dp[k];继续运行{}里面的内容 }

 

所以,可以用很简单的代码来解决这个问题:

    dp[0] = -1;    for (i = 1; i < N; i++)    {       j = i - 1;       while (j != -1 && arr[j] >=arr[i]) j = dp[j];       dp[i] = j;       }

上面代码的复杂度是O(n),可能会有很多人疑惑,明明是一个for里面套了一层while,怎么会是O(n)呢。

 

这里需要用到平摊分析的方法,我们来思考一下,在整个计算过程中dp[k]被访问的次数,一次赋值是必须的。然后呢,如果在计算dp[i]过程中,while循环体中使用了k = dp[k],那么dp[i] <=dp[k]<k<i(i>k),在计算i之后元素m时,如果arr[m]>arr[i],那么往前最多访问到dp[i],dp[k]不会被访问,如果arr[m]<=arr[i],那么在while中使用了dp[i]就不可能再使用到dp[k] (参考dp[i]<=dp[k]<k<i),所以,每个k=dp[k]在while循环中最多使用1次,综合起来,复杂度就是O(n)

 

2.下面给出一个可以抽象成上述问题的题目:Largest Rectangle in a Histogram

A histogram is apolygon composed of a sequence of rectangles aligned at a common base line. Therectangles have equal widths but may have different heights. For example, thefigure on the left shows the histogram that consists of rectangles with the heights2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles: 


Usually, histograms are used to represent discrete distributions, e.g., thefrequencies of characters in texts. Note that the order of the rectangles,i.e., their heights, is important. Calculate the area of the largest rectanglein a histogram that is aligned at the common base line, too. The figure on theright shows the largest aligned rectangle for the depicted histogram.

 

解法为:

对数组arr[0..N-1]

求得dp[0..N-1],代表左侧最近小于当前值的位置

求得rdp[0..N-1],代表右侧最近小于当前值的位置

注意求dp和rdp方法是相同,dp[0] = -1,rdp[N-1] = N

那么最终答案为 max{ (rdp[i]-dp[i]-1)*arr[i]} 其中0<= i <= N-1,复杂度O(n)

因为对于一个满足条件的面积最大矩形,它的高必定和它包括的某个柱高相同,即arr[i]

 

3.求0-1矩阵中的最大1矩阵

给定一个0-1矩阵,就其中包含1个数最多的子矩阵。

如maze[0..N-1][0..M-1]

我们枚举最大1矩阵的底边在maze的第i行,然后用arr[j]记录从maze[i][j]到maze[0][j]过程中(纵向)包括maze[i][j]且最长的连续1个数,那么这个问题就转化为问题2了,这个子问题复杂度为O(m)

 

那么整体复杂度为n*O(m) = O(n*m)

原创粉丝点击