coding everyday

编程面试题 https://interview.codeplex.com

C++博客 首页 新随笔 联系 聚合 管理
  12 Posts :: 2 Stories :: 7 Comments :: 0 Trackbacks

#

本题目出自@陈利人

问题:
#Google面试题#给你一天的Google搜索日志,你怎么设计算法找出是否有一个搜索词,它出现的频率占所有搜索的一半以上?如果肯定有一个搜索词占大多数,你能怎么提高你的算法找到它?再假定搜索日志就是内存中的一个数组,能否有O(1)空间,O(n)时间的算法?

刚看到这个题目的时间吓坏了,好难啊,无从下手啊,为自己的之上捉急啊。。下班的班车上开始想这个问题,开始分析,其实这个搜索日志就是一个搜索词的集合嘛,甭管它有多大,总可以分成若干堆吧。既然这个搜索词超过一半,那么在这若干堆中分别找出来最流行的词中,也应该占一半吧。(这个应该没有理解错吧。)

这个时候我想可以把问题转换成一个整数数组,其中有个整数出现的次数超过一半,找出这个整数就OK了吧。要找出这个数组中出现次数超一半的值,本身这个算法应该很简单,但是O(1)空间和O(n)的时间复杂度,还是有点伤脑筋的。。:(,内存又不贵,为啥O(1)啊。。

因为那个数字出现的次数超过一半,我们可以想象一下,把那个数字标成1,其它的都是-1,把所有的数字加起来肯定大于0,对吧?因为超过一半嘛。。这个时候灵光乍现,用一个标杆来标志潜在的那个搜索词,一个整数count表示它出现的次数(准确的说不是它的次数,后面会解释),遍历整个数组
1)   如果当前的跟标杆一样,count++
2)   如果不相等,--count,若此时count为0,则把当前值置为标杆,count为1
重复1), 2)即可,最后那个标杆即为最流行搜索词。

代码简单的我不能相信,以至于我觉得我肯定理解错误题目的意思了,不管怎么样上下代码 
 1 // Get the most popular searching keyword in Google. :)
 2 template<typename T>
 3 T get_most_popular_keyword(const T *list, int size) {
 4     T result = list[0];
 5     int count = 0;
 6 
 7     for (int i=0; i<size; i++) {
 8         if (list[i] == result)
 9             count++;
10         else {
11             if (--count == 0) {
12                 count = 1;
13                 result = list[i];
14             }
15         }
16     }
17 
18     return result;
19 }
posted @ 2013-07-02 21:10 everyday 阅读(333) | 评论 (0)编辑 收藏

本文描述的是我自己的一个失败的挑战经历。

题目
两个单链表(singly linked list),每一个节点里面一个0-9的数字, 输入就相当于两个大数了。然后返回这两个数的和(一个新list)。这两个输入的list 长度相等。 要求是:1. 不用递归。2. 要求算法在最好的情况下,只遍历两个list一次, 最差的情况下两遍。

我的算法是: 2次遍历是肯定能的,第一次相加并以倒序存,第二次进位并倒序。一次/两次的算法,用2个指针,一个指钱一个,另一个指向再前一个,另一个flag标志是否走第二轮。只有前前位有进位flag置true跑第二次。

为啥当时会有这样的想法呢?因为所有数字都是0~9,所以我假设了第一轮的相加和进位能把大部分该进位的都进了,所以如果存在需要第二轮的话,找出那个条件就好了。当时就沿着这个思路走了。当然大部分情况下这个算法是可行的,但是这里有个很明显的漏洞,当时被胜利冲昏头脑的我怎么会想的到呢?就是一开始没有出现进位,后来连续进位的情况,如@赵小罡这位朋友设计的用例 1000001+9999999。一并感谢其他指出错误的网友。

如果有人想怀着鄙视的心态看下我错误的代码,请点击“源码",不过放在心里就好了,不要打击我脆弱的心灵哦。:)

另外有个高手做了一个算法,总是只要一次就能搞定的。@hawstein详情见“求两个单链表的和” 尼害的不得了。他的网站上还有不少好东西呢。对于他的算法,我有个改进的建议就是,以他的算法完全没有必要单独考虑第一个节点的情况,在遍历结束后,判断下第一个节点是否大于9就OK了,如果大于9,最前面插入一个节点。
posted @ 2013-07-02 09:51 everyday 阅读(403) | 评论 (0)编辑 收藏

仅列出标题
共2页: 1 2