度娘笔试归来,题目实打实的,感觉真心不易,上百号人就抢那么几个坑......只恨自己平时积累太少啊~

  故曝一道鹅厂面试用的算法题(当时我就死在了这题上),来为度娘家攒一下RP~


  题目:

     对于长度为N的一个无序的数组a[1..N],请将a进行排序,要求所有正数都排在0之前,所有负数都排在0之后(如果没有0,则所有正数排在负数前)

     要求时间复杂度O(N),空间复杂度O(1) 

  


  题目不难,但给思考的时间很短,大约不到5分钟吧。当时脑子比较短路,于是只给出了O(n) O(n)复杂度的算法,然后就被面试官挂掉了.....

  更杯具的是,走出门就恍然大悟了~


  solution:

     这是一道类排序题,它并不要求严格的一一排序,难点在于如何将排序要求的降低转化为时间与空间的节省。

     首先,起点是快排,O(N*logN)的时间复杂度,我们的算法需要比快排更快。O(N),即遍历一遍数组即完成排序。

       很容易想到的是,题目只分正数/0/负数,如果在遍历数组的时候,将遇到的正数都塞到数组的头部,负数都塞道数组的尾部,即能在遍历一遍的情况完成。

     问题是,在数组结构中,将某个数塞至头部/尾部,需要一位一位的移位,这意味着每次移位都要O(N)/2的时间复杂度,这是不能忍的!

     那么如何做,才能保证O(1)的时间复杂度内完成移位呢?

     当时,我想到的是新建一个空数组b[1..N],

          定义两根指针i,j,i<-1,j<-N。

          然后遍历数组A,

            如果A[k]>0,则b[i]=A[k],i++;

                反之,则b[j]=A[k],j--。

     这样的做法达到了O(N)的时间复杂度要求,但新建的数组b则超过O(1)的空间复杂度。事实上,面试官一开始并没有要求空间复杂度。   

     这样的话,只能在原数组进行操作了,移位又太慢,就只能交换了。交换的话,问题在于和哪一位上的元素进行交换?

     我们不妨用数学归纳法来表征这个问题:

       假设在遍历到第m位的时候,a[1..m]能满足“正数<<0<<负数”,如何操作a[m+1],使得a[m+1]也满足上述条件呢?

          如果a[m+1]=负数,那么我们就不用动它;

          如果a[m+1]=0,我们就将它与排在最前面的负数交换;

          如果a[m+1]=正数,会比较麻烦,我们要将它与最在最前的0交换,然后就将问题转化成了a[m+1]=0的情况。

       综上,我们也需要两根指针i,j。i<-连续的正数序列中最后的那位,j<-连续的0序列中最后的那位。并在m++后,更新i,j即可。

             

伪代码如下:

     int a[N];
a=random(N);
    int m=;
while(a[m]<=) m++;
swap(a[],a[m]);
int i=,j=;
    for(int m=;m<N;m++)
      if(a[m]==){
        swap(a[m],a[j+]);
j++;  
      }else if(a[m]>0) {
swap(a[m],a[i+]);
i++;
swap(a[m],a[j+]);
j++;
}

        

      

[solution]腾讯TEG_计算广告组_算法题的更多相关文章

  1. ML学习分享系列(2)_计算广告小窥[中]

    原作:面包包包包包包 改动:寒小阳 && 龙心尘 时间:2016年2月 出处:http://blog.csdn.net/Breada/article/details/50697030 ...

  2. ML学习分享系列(1)_计算广告小窥[上]

    原作:面包包包包包包 修改:寒小阳 && 龙心尘 时间:2016年1月 出处: http://blog.csdn.net/breada/article/details/50572914 ...

  3. [Computational Advertising] 计算广告学笔记之基础概念

    因为工作需要,最近一直在关注计算广告学的内容.作为一个新手,学习计算广告学还是建议先看一下刘鹏老师在师徒网的教程<计算广告学>. 有关刘鹏老师的个人介绍:刘鹏现任360商业产品首席架构师, ...

  4. 海量数据挖掘MMDS week5: 计算广告Computational Advertising

    http://blog.csdn.net/pipisorry/article/details/49428053 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...

  5. 云之讯融合通讯开放平台_提供融合语音,短信,VoIP,视频和IM等通讯API及SDK。

    云之讯融合通讯开放平台_提供融合语音,短信,VoIP,视频和IM等通讯API及SDK. undefined 全明星之极验证 - SendCloud undefined [转载]国内外几个主流的在线开发 ...

  6. 未来已来,腾讯AI计算网络

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:由鹅厂网事发表在云+社区 "鹅厂网事"由深圳市腾讯计算机系统有限公司技术工程事业群网络平台部运营,我们希望与业界各位志同道合的伙伴交流 ...

  7. 问题:计算foldRight(1)(_-_) 与foldLeft(1)(_-_)值不一样

    List(1,2,3,4)问题:计算foldRight(1)(_-_) 与foldLeft(1)(_-_)值不一样首先看foldRight(1)(_-_)计算过程((( (1-1)-2)-3)-4) ...

  8. 计算广告学-多点归因模型(Multi-Touch Attribution Model)

    计算广告学中的一个重要的问题是, 如果用户产生了一次转化(conversion, 比如购买, 注册等), 且该用户在转化之前看过大量不同频道(比如搜索, 展示, 社交等等)的广告, 那么我们如何确定是 ...

  9. 实时竞价RTB广告平台_传漾科技_中国领先的智能数字营销引擎

    实时竞价RTB广告平台_传漾科技_中国领先的智能数字营销引擎 Programmatic Framework™ 传漾程序化购买框架

随机推荐

  1. Eclipse Debug时出现Source not found错误

    今天在Debug Java代码时报出了Source not found这个错误,如下图所示,经过查询资料得知这是由于缺少Hadoop源程序代码所导致的错误. 在此我建议了两种方法,可以先采用方法一,这 ...

  2. Linux netstat命令详解和使用例子(显示各种网络相关信息)

    netstat命令用于显示与IP.TCP.UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况.netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP ...

  3. SpringBoot 封装返回类以及session 添加获取

    1.创建返回类Result public class Result<T>{ /*错误码*/ private Integer code; /*提示信息 */ private String m ...

  4. 关于如何将html中的表格下载成csv格式的方法

    今天在网上看了很多方法,自己还是慢慢探索写出了最终效果 简单代码如下: <!DOCTYPE html> <html> <head> <meta content ...

  5. Linux中gzip、bzip2、zip、unzip、tar使用介绍

    压缩解压缩命令介绍.gz 压缩为gzip文件.bz2 压缩为bzip2文件.tar 打包文件,将多个文件合并成一个目录.tar.gz 先打成tar包,再压缩为gzip文件.tar.bz2 先打成tar ...

  6. 运行JavaWeb项目报错Access denied for user 'root'@'localhost' (using password: YES)

    问题重现:(以下讨论范围仅限Windows环境): C:\AppServ\MySQL> mysql -u root -p Enter password: ERROR 1045 (28000):  ...

  7. POJ 2923 Relocation(01背包+状态压缩)

    题意:有人要搬家,有两辆车可以运送,有若干家具,车有容量限制,而家具也有体积,那么如何运送会使得运送车次最少?规定两车必须一起走,两车一次来回只算1躺. 思路:家具怎么挑的问题,每趟车有两种可能:1带 ...

  8. [VC]关于ocx控件的自己编写的dll问题

    要是无法删除c:windows/cownloadprogrames下的文件时可以关掉所有的浏览器,然后在internate----程序---管理 加载项里 先把那个加载项 更新一下,或者禁用一下,或者 ...

  9. CAD控件的鼠标事件(网页版)

    _DMxDrawXEvents::MouseEvent CAD控件中的鼠标事件. 参数 说明 LONG lType 事件类型,1鼠标移动,2是鼠标左键按下,3是鼠标右键按下,4是鼠标左键双击 5是鼠标 ...

  10. JavaScript onkeydown事件入门实例(键盘某个按键被按下)

    JavaScript onkeydown 事件 用户按下一个键盘按键时会触发 onkeydown 事件.与 onkeypress事件不同的是,onkeydown 事件是响应任意键按下的处理(包括功能键 ...