面试算法题1

来源:互联网 发布:c语言中swap的用法 编辑:程序博客网 时间:2024/06/11 01:34
  1. 一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。
    请设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。
    注意:
    - 5个数值允许是乱序的。比如: 8 7 5 0 6
    - 0可以通配任意数值。比如:8 7 5 0 6 中的0可以通配成9或者4
    - 0可以多次出现。
    - 复杂度如果是O(n2)则不得分。

分析:很容易想到的方法是先排序,然后记录0的个数,然后继续遍历该数组,如果连续两个数非相邻,则记录他们的差-1,比如排序后的结果位0 0 5 7 8,  0的个数为2,另外5,7非相邻,用一个计数器c记为1,最后判断计数器的值是否不大于0的个数,是的话则可以满足条件,显然0 0 5 7 8是满足条件的。比如0 0 5 8 10,计数器c应为 (8-5)-1 + (10-8)-1=3 而0的个数为2,因此非连续相邻。时间复杂度为排序O(nlgn),另外需要遍历一遍O(n),总时间复杂度为(Onlng)。

会不会有更好的办法呢?其实0 0 5 7 8 和 0 0 5 6 8对于我们的结果是不影响的,也就是说除了最大数和最小数之外的我们并不care。对了,所以我们只需要找出最大的数字max,最小的数字min,0的个数k,然后判断max-min+1-(5-k)<=k,化简下max-min<=4,呃,其实与0的个数无关的,换个思路其实很好理解了,假设只有两个数,其它的都是0,那么这种情况我们很容易想到a-b+1<=5;然后再想上面的情况应该就很好明白了。时间复杂度的话,就取决于找最大数和最小数,O(n)。OK,那最好的方法找最小数和最大数是什么呢?