还有三个小时面Youtube。。。嗓子还哑了,尼玛,三番冷死人了。不知道来干嘛。。。
18.1 加和两个数字,不使用算数符号,(那特么不就是要用binary的意思嘛!)
1101^1001 = 0100 ==> add without carry
1101&1001 = 1101 , 1001<<1 = 10010 ==> carry without add
1101 + 1001 = 10110
然后recursion,这种题我觉得考到必死。。。但是值得记住。。。。
18.2 把一个deck的扑克shuffle一遍。
第一个问题,回忆一下,如何implement一桌扑克,基本上扑克就是花色和数字,所以可以考虑就是一张牌是一个class,
包含花色和数字。好像也没啥别的。
第二个问题,对于任何一坨数列,如何找到random permutation。
回忆一下如何search for all permutation, 做法是把第一个数字和后面的所有数字swap一遍,然后进入下一层,干同样的事情。
现在的问题就是,对于任何一坨数列,如何做random permutation的sampling,基本上就是每个element都有等同的机会出现在某个element的地方
我的想法是,对于任何两个做一次random的交换,其实和做full search是一样的。
书上最后给出的这个做法非常好,我用python写下来
def shufflearray(cards):
for i in xrange(len(cards)):
k = random.randint(0,i)
card[i],card[k] = card[k],card[i]
这个算法的含义是,shuffle(n)可以是shuffle(n-1),再加上n和shuffled n-1 里面的任何一个排交换
18.3 写一个在n里面randomly拿到m个数的算法
这类题首先知道的是,一直摇色子,取数取到够为止到底行不行。
貌似应该是可以的。但是书上并没有说这种。但是至少这个方法有点慢。。。。
书上给出的方法是这样,讨论,如果我知道如何在n-1里面拿出m个,然后是不是只需要找一个随机位置,然后交换就可以了
我突然意识到这个的主要难度在于,base case是啥情况?
base case是m等于n的时候,那时候就直接返回就行了。
18.4 写出在0-n之间有多少个2
第一种方法就是brutal force计算,第二种有点复杂,就算了把
18.5 在一个很大的文件里,给两个单词,找到shortest distance。
我想到的第一个办法是做一个hashmap,然后value是所有的位置,没了。
书上给出了一个计算两个set的最短距离的方法,就是把两个set带tag地merge起来,sort之后。然后寻找最接近的两个
这个算法是O(nlogn),还是提高了不少了的
18.6 找到一个数列里面前M个最大的。
sort, min_heap, selection rank (基本上就是quick sort),做很多次,做到成功为止。
感觉heap方面还得再看看。。。。
18.7 给一列单词,找到到由其他单词组成的最大单词。
似乎还是那个题,solution[n] = solution[n-1]+word[n].length() if solution[n-1] is feasible
书上给出另外一个做法,先sort,然后从大到小,看单词的左半部分和右半部分是不是都在序列里。
确实要简单一些。
18.8 Trie
这题就是google的二面啊。当然二面比这个难多了,我当时写的是一个dictionary的结构
并没有使用树的结构,一直很好奇如何生成树结构,看了这题我才知道,不管怎么弄都是一个
nested dictionary
18.9 Maintain a median value in a stream
用heap似乎是个不错的主意。第一个问题是,有没有可能maintain一个median heap,貌似略微难
有没有可能做两个heap,一个max,一个min, 这样似乎maintain的是(max+min)/2没啥意义,而且这个不存在delete的operation
做两个heap,max heap的最大数小于min heap的最小数,然后保持size,不然就移动?minheap.add(maxheap.pop)
书上也是这么做的,不过可以maintain一个median,这个没啥区别。
关于python的heap:
import heapq
heapq.heapify(a)
heapq.heappush(a,new)
heapq.heappop(a)
18.10 在字典里面有两个单词,要求找到一个path,path上得每一个单词都和这个单词有一个字母变化
咋看咋觉得是BFS呢?。。。
但是BFS如何记录path呢?只能maintain一个child->parent的dictionary
书上确实是这么做的。。。
18.11 找到一个矩阵里面最大的黑框正方形
preprocessing比较有用。
18.12 max sum sub matrix
这题感觉是max sub array的升级版本
是不是可以直接用sub array来做呢?只标记sub matrix的底角,然后一行一行的扫描,但是不知道对不对。。
O(n^3), 我居然对了,尼玛,这运气,第三种方法。。。。
书上的第二种方法给出了一个比较有意思的例子,关于如何用DP计算一个submatrix的和的, 其实就是最基础的集合论思想
s(x,y) = s(x,y-1)+s(x-1,y)-s(x-1,y-1)+M(x,y)
18.13 给一个巨大的词库,要求你做出来一个matrix,each row和each column都是词,还要largest possible
最后一题
我能想到的方法就是一个一个地试,这样似乎一个巨大的trie可以解决很多问题。
从最大的单词横着摆开始,然后从第一个字母开始尝试竖着的,然后尝试第二个字母,如何没有那样开头的就直接挂掉
有了之后再做第二层列向的。
书上的第一句话是,和字典有关的题目通常都可以preprocessing
书上使用了trie,但是先group了相同长度的单词。 然后一层一层地堆,同时检测开头单词的是不是存在
大约就是这样,剩下的实在看不下去了。
---------------------------------------------------------------------------------------------------------------------------------------------------------
就这样吧,如果fb给了面试,我就写一下thread lock那段。