codility上的问题(25) Omega 2013

这个题有意思。

有一口井,井的高度为N,每隔1个单位它的宽度有变化。现在从井口往下面扔圆盘,如果圆盘的宽度大于井在某个高度的宽度,则圆盘被卡住(恰好等于的话会下去)。每隔盘子有几种命运:

(1) 掉到井底

(2) 被卡住

(3) 落到别的盘子上方

盘子的高度也是单位高度。给定井的深度和每个盘子的宽度,求最后落到井内的盘子数。


如图井和盘子信息如下:

  A[0] = 5    B[0] = 2
  A[1] = 6    B[1] = 3
  A[2] = 4    B[2] = 5
  A[3] = 3    B[3] = 2
  A[4] = 6    B[4] = 4
  A[5] = 2
  A[6] = 3

返回4。

数据范围 井深度 N [1..200000], 盘子个数M [1..200000], 数组元素都在[1..10^9]

要求复杂度: 时间 空间都是O(N)。

分析; 这个题不难。如果一个盘子j能落到第i层,必须min{A[0..i]} >= B[j],所以我们记录最小值就可以了。

如果记录最小值的下标,向上找的可以“快”一点,但是空间复杂度要O(N)。

因为最多N个盘子,所以时间复杂度O(N)。

代码:

// you can also use includes, for example:
// #include <algorithm>
int solution(vector<int> &A, vector<int> &B) {
    // write your code here...
    int n = A.size(),i, h;
    vector<int> height;
    height.resize(n);
    height[0] = 0;
    for (i = 1; i < n; ++i) {
        height[i] = (A[i] < A[height[i - 1]])?i:height[i - 1];
        
    }
    for (i = 0,h = n - 1; (h >= 0) && (i < B.size()); --h, ++i) {
        for  (;(h >= 0) && (A[height[h]] < B[i]) && (h >= 0); h = height[h] - 1)
        ;
        if (h < 0) {
            break;
        }
    }
    return i;
}


我们利用A数组的值,存放前i项的最小值的话可以有空间复杂度为O(1)的算法。


// you can also use includes, for example:
// #include <algorithm>
int solution(vector<int> &A, vector<int> &B) {
    // write your code here...
     int n = A.size(),i,r = 0;
     for (i = 1; i < n; ++i) {
         A[i] = min(A[i - 1], A[i]);
     }
     for (i = 0; i < B.size();++i) {
         for (--n; (n >= 0) && (A[n] < B[i]); --n)
         ;
         if (n >= 0) {
             ++r;
         }
         else {
             break;
         }
     }
     return r;
         
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值