查看: 2848| 回复: 5
跳转到指定楼层
上一主题 下一主题
收起左侧

Google : 找最小窗口

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
Given array A and B, write a function to find the smallest window in A that covers all numbers in B

上一篇:Google : 位逆序
下一篇:google : Organize football tournament
🔗
darksteel 2011-5-23 03:37:13 | 只看该作者
全局:
本帖最后由 darksteel 于 2011-5-23 03:41 编辑

回复 1# wwwyhx
小声说一句,这题你前面发过了

这题应该能做到O(kn)。假设数组是a[1..n]和q[1..k]。
dp[n][k]: dp[ i][j]表示从a[ i]开始,包含q[j...k]的最小窗口的长度。初只全部设为INF。
for i = 1 to n
  if a[ i] == q[k]
    dp[ i][k] = 1;
for i = k-1 to 1
  p = -1;
  for j = n to 1
    if a[j] == q && p > 0
      dp[j][ i] = dp[p][i+1] + p - j;
    if a[j] == q[i+1]  p = j;
最后答案是dp[ i][1]之中最小的那个。
以上伪代码可能有漏洞,但大体思路是这样。假设某个位置a[ i]的值等于q[1],要找严格从这个位置开始的最小窗口,我们总是可以用贪心的策略,找到第一个q[2]就继续找q3],然后找到第一个q[3]就开始找 q[4],跳过某个不会使解更优。所以每次内层循环我们只要维护一个离当前最近的q[i+1]的位置,直到找到一个q[ i],然后可以直接通过dp[p][i+1]得出dp[j][ i]。细节还有可以简化的地方,空间好像也能优化到O(n)。欢迎指出漏洞。
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-5-25 21:48:36 | 只看该作者
全局:
本帖最后由 wwwyhx 于 2011-5-25 21:58 编辑

回复  wwwyhx
小声说一句,这题你前面发过了

这题应该能做到O(kn)。假设数组是a[1..n]和q[1..k]。
dp[n][k]: dp[ i][j]表示从a[ i]开始,包含q[j...k]的最小窗口的长度。初只全部设为INF。
for i = 1 to n
  if a[ i] == q[k]
    dp[ i][k] = 1;
for i = k-1 to 1
  p = -1;
  for j = n to 1
    if a[j] == q && p > 0
      dp[j][ i] = dp + p - j;
    if a[j] == q  p = j;
最后答案是dp[ i][1]之中最小的那个。
以上伪代码可能有漏洞,但大体思路是这样。假设某个位置a[ i]的值等于q[1],要找严格从这个 ...
darksteel 发表于 2011-5-23 03:37


不对吧,第一眼的感觉因该就是两个指针一个快一个慢,一开始都从起始点开始,不满足条件的话加快指针,满足条件后加慢指针缩小窗口,达到第一个最小窗口后移动一格慢指针使重新不满足条件,再次找第二个最小窗口,这样可以找出所有的最小窗口,记录最小的那个最小窗口。
要设计一个hash数据结构能方便的知道是否窗口能覆盖那个小数组
回复

使用道具 举报

🔗
darksteel 2011-5-28 14:17:25 | 只看该作者
全局:
回复 3# wwwyhx
这个就是最朴素的办法吧,就是从每个位置都向后找一遍,这样最坏可能是n^2,虽然中间可以略过一些,但应该不会有本质的提高。我觉得是可以做到kn的
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-5-28 14:28:24 | 只看该作者
全局:
回复  wwwyhx
这个就是最朴素的办法吧,就是从每个位置都向后找一遍,这样最坏可能是n^2,虽然中间可以略过一些,但应该不会有本质的提高。我觉得是可以做到kn的
darksteel 发表于 2011-5-28 14:17



    不是O(n^2),是O(n)
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-5-28 14:35:56 | 只看该作者
全局:
编程很麻烦,道理就是这个,时间复杂度O(2n+m),空间复杂度O(m),编程需要有些技巧来判断窗口的移动是否会让窗口从全部包含B到缺一个,或从不全包含到全包含,这两点做到O(1).

先用O(m)的时间复杂度建立O(m)的hashtable,  再用O(2n)的时间复杂度遍历A,遍历的过程不是O(n^2)的枚举。“两个指针一个快一个慢,一开始都从起始点开始,不满足条件的话加快指针,满足条件后加慢指针缩小窗口,达到第一个最小窗口后移动一格慢指针使重新不满足条件,再次找第二个最小窗口,这样可以找出所有的最小窗口,记录最小的那个最小窗口”, 就这个步骤的时间复杂度是O(2n)

hash node 的结构可以用
struct HASH_NODE
{
        int nVal; // 值
        int nFreqA; //当前在A窗口中出现的次数
        int nFreqB; //在B中出现的次数
        HASH_NODE* pNodeNxt;
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表