两道微软面试题

[题记]

猎头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. //
  2. // 解法1:本算法采用的是动态规划原理。
  3. // 时间复杂度,大概是O(N)
  4. // 即:假设这个字符为M,如果每次删除两个不同的字符(不管是否包含M),那么,
  5. //在剩下的字符列表中,M出现的次数仍然超过总数的一半。
  6. // 可以不断重复这个过程,把字符串的字符总数降低(转化为更小的问题),
  7. //从而得到问题的答案。总的时间复杂度为O(n),只需对字符串扫描一遍。 
  8. char find(char str[])
  9. {
  10.     char temp = NULL;
  11.     int occurs = 0;
  12.     int length = strlen(str);
  13.     for ( int i = 0; i < length; i++) {
  14.         if (0 == occurs ) {
  15.             temp = str[i];
  16.             occurs++;
  17.         } else {
  18.             if ( temp == str[i])
  19.                 occurs++;
  20.             else
  21.                 occurs--;
  22.         }
  23.     }
  24.     //
  25.     // 上面的算法是经典实现。但是有个问题:如果不存在超过50%的字符串,
  26.     // 那么返回值就是错误的,比如:"abbccddex"
  27.     // 所以还需要增加如下的检测:
  28.     for ( i = 0; i < length; i++) {
  29.         if (temp == str[i] )
  30.             occurs++;
  31.     }
  32.     if ( occurs <= (length /2 ))
  33.         temp = '/n';    
  34.     //
  35.     return temp;
  36. }
  37. //
  38. // 解法2: 主元素问题
  39. // 采用概率算法,随机抽取某个元素进行统计,时间复杂度大概是n*lg(n)
  40. // 但是也不太好
  41. int main(int argc, char* argv[])
  42. {
  43.     printf("Hello World!/n");
  44.     
  45.     char str[] = "bcbdbexxxxd";
  46.     char chr = find(str);
  47.     if ( '/n' != chr)
  48.         printf("%c/n", chr);
  49.     else 
  50.         printf("no occurs/n");
  51.     char str2[] = "abbccddex";
  52.     chr = find(str2);
  53.     if ( '/n' != chr)
  54.         printf("%c/n", chr);
  55.     else 
  56.         printf("no occurs/n");
  57.     getch();
  58.     return 0;
  59. }

[后记]
说明,一般说来X就是牛的意思,XXX就是很X的意思。

反正是这样的,出题的肯定要难倒做题的;所以,我做不出来是正常的,什么题都能做得出来,就是他出题的人水平有问题了。想着想着,我觉得心里很释然。

另外,这几天上网看了一些相关的算法题目,很费劲,很没有兴趣。于是,自己想了想,觉得自己好像真的不适合在这方面深入下去;那么前景是什么那?应用级开发,项目管理,然后那?我踌躇满志的在glass ceiling 下面疑惑,思考。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值