寻找最近的小于当前数的位置
来源:互联网 发布: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)
- 寻找最近的小于当前数的位置
- 寻找距离某数最近的素数(C语言)
- 汇编用串检测scasb寻找数的位置
- lower_bound upper_bound源代码,以及小于等于关键词最大的数的位置
- 小于65536的数的十六进制数
- 小于256任意数的二进制数
- 寻找重复的数
- 寻找重复的数
- 寻找独一无二的数
- 寻找缺失的数
- 寻找丢失的数
- 寻找缺失的数
- 寻找缺失的数
- 寻找缺失的数
- 寻找子串的位置
- 获取当前的位置
- 最近的Fibonacci数
- C++学习笔记-----二分法之寻找非减序列第一个大于某个值的数或最后一个小于某个值的数
- window Timers 定时服务
- 经典C++笔试题解析1
- set的使用 (ex34.sh)
- printf输出格式大全
- Ubuntu 12.10搭建tftp和nfs服务器
- 寻找最近的小于当前数的位置
- 再一次声明, 不要使用(include/require)_once
- SQL2005存储过程解密
- c#中的@符号
- 怎样给心爱的Csharp应用程序添加图标
- HDU 4435 charge-station(12年天津)
- Head First 设计模式第一章 ----策略模式
- 刚有人问面试题咋答,一时兴起回了下,关于对 Struts2, Spring 和 Hibernate 的理解
- GDI:捕捉鼠标,实时改变矩形背景颜色。