[题记]
猎头J看中了我,非要让我去M$;去就去吧,还非要面试;面就面吧,还非得出难题,真是的;简简单单的走走过场就行了吧,呵呵。这两个题目是hr给我出的题目之二(此处,hr需要强调,非常强调),我没有回答正确或者根本就不能回答。
[正文]
1,你让工人为你工作7天,回报是一根金条,这个金条平分成相连的7段,你必须在每天结束的时候给他们一段金条。如果只允许你两次把金条弄断,你如何给你的工人付费?
[hisense-> XXX] 这个题我知道答案
[hisense-> XXX] 但是不知道该如何解释这个理论
[XXX-> hisense] 二进制
[hisense-> XXX] 如果把这个数字换为25,分5分那?
[hisense-> XXX] 就不是2进制了
[hisense-> XXX] 3进制和4进制都行
[XXX-> hisense] 3进制怎么分?
[hisense-> XXX] 1,2,3,6,13
[hisense-> XXX] 4进制就不行了
[XXX-> hisense] 要是26分5份,你怎么办?3进制就不行了。
[hisense-> XXX] 对。所以说,我找不到理论
[hisense-> XXX] 只能有一个这样的简单结论:如果M个分N份,那么前面N-1分的和>=第N分的值。
N个时间单位过去了...
[XXX-> hisense] 还有一个结论,对于第k项ak,前k-1项的和大于等于ak-1,这个可能更有用。
[XXX-> hisense] 这样可以推出一个结论2*a[k]>=a[k+1]
[hisense-> XXX] 对,有道理
[hisense-> XXX] 这样就可以解释通了
[hisense-> XXX] 实际上和2进制、3进制就无关了,对吧
[XXX-> hisense] 我觉得是。
[hisense-> XXX] 好,就这样了,谢谢。
结论:有解。2*a[k]>=a[k+1]
2,
任意长度字符串,其中只包含字母,找出其中某个字符,他的长度占整个字符串长度的50%。我知道用hashtable,但是还有提高的余地,我怎么也没想出来。
[XXX-> hisense] 我要想想。
[hisense-> XXX] 当时他给了我一个提示,但是我还是不知道该如何继续:
[hisense-> XXX] 如果M的出现次数大于50%,那么其他所有的字母出现的次数和必定小于50%。比方说,M=60%,其他=40%,那么60-40=20.
[hisense-> XXX] 而且,对于其他的字母来说,是不需要进行出现次数的统计的;换句话说,如果对所有的字符出现个数都进行了统计,那么就是性能浪费。
[hisense-> XXX] 但是我不知道该如何节省这个性能的浪费
[XXX-> hisense] 关键是我们怎么知道那个是最大的?
[hisense-> XXX] 对啊,这个最大实际上是事后统计出来的。
[XXX-> hisense] 如果用消去的办法有可能吗?用字母逐个删除指定的个数。比如删除一个a、一个b、一个c,然后再来一轮,但是,好像这样的效率也不高。需要查找很多次。
[hisense-> XXX] 好像那个人有这方面的提示,就是消去什么。但是我感觉效率不高
[hisense-> XXX] 可以一轮就吧所有的字符都消掉整个字符串长度的40%
[hisense-> XXX] 不够的就算了,还有没消掉的就是候选
[hisense-> XXX] 还是需要计数,不行
N个时间单位过去了...
[hisense-> XXX] 就你这速度,早被M$鄙视了,呵呵
结论:不知道如何解。
[20081209, 补记]
知道答案了,看代码:
- //
- // 解法1:本算法采用的是动态规划原理。
- // 时间复杂度,大概是O(N)
- // 即:假设这个字符为M,如果每次删除两个不同的字符(不管是否包含M),那么,
- //在剩下的字符列表中,M出现的次数仍然超过总数的一半。
- // 可以不断重复这个过程,把字符串的字符总数降低(转化为更小的问题),
- //从而得到问题的答案。总的时间复杂度为O(n),只需对字符串扫描一遍。
- char find(char str[])
- {
- char temp = NULL;
- int occurs = 0;
- int length = strlen(str);
- for ( int i = 0; i < length; i++) {
- if (0 == occurs ) {
- temp = str[i];
- occurs++;
- } else {
- if ( temp == str[i])
- occurs++;
- else
- occurs--;
- }
- }
- //
- // 上面的算法是经典实现。但是有个问题:如果不存在超过50%的字符串,
- // 那么返回值就是错误的,比如:"abbccddex"
- // 所以还需要增加如下的检测:
- for ( i = 0; i < length; i++) {
- if (temp == str[i] )
- occurs++;
- }
- if ( occurs <= (length /2 ))
- temp = '/n';
- //
- return temp;
- }
- //
- // 解法2: 主元素问题
- // 采用概率算法,随机抽取某个元素进行统计,时间复杂度大概是n*lg(n)
- // 但是也不太好
- int main(int argc, char* argv[])
- {
- printf("Hello World!/n");
- char str[] = "bcbdbexxxxd";
- char chr = find(str);
- if ( '/n' != chr)
- printf("%c/n", chr);
- else
- printf("no occurs/n");
- char str2[] = "abbccddex";
- chr = find(str2);
- if ( '/n' != chr)
- printf("%c/n", chr);
- else
- printf("no occurs/n");
- getch();
- return 0;
- }
[后记]
说明,一般说来X就是牛的意思,XXX就是很X的意思。
反正是这样的,出题的肯定要难倒做题的;所以,我做不出来是正常的,什么题都能做得出来,就是他出题的人水平有问题了。想着想着,我觉得心里很释然。
另外,这几天上网看了一些相关的算法题目,很费劲,很没有兴趣。于是,自己想了想,觉得自己好像真的不适合在这方面深入下去;那么前景是什么那?应用级开发,项目管理,然后那?我踌躇满志的在glass ceiling 下面疑惑,思考。