posts - 297,  comments - 15,  trackbacks - 0
(说明:这些题就不是什么花样了,考的是你的基础知识怎么样。再聪明而没有实学的人都将会被这些题所淘汰。) 
1.链表和数组的区别在哪里?

ANSWER 主要在基本概念上的理解。但是最好能考虑的全面一点,现在公司招人的竞争可能就在细节上产生,谁比较仔细,谁获胜的机会就大。

1)数组在内存中是逐个存放的,也就是说倘若数组的第一个元素在地址A,则数组第二个元素就在地址A+1。而链表则不是,链表每个节点没有相对固定的位置关系。某个节点在地址A其后的节点不一定是A+1,而在内存的其他空闲区域,呈现一种随机的状态。

2)数组一旦显式的被申明后,其大小就固定了,不能动态进行扩充。而链表则可以,可以动态生成节点并且添加到已有的链表后面。

3) …… (大家一起想想)

 

2.编写实现链表排序的一种算法。说明为什么你会选择用这样的方法?

ANSWER 链表通常是插入排序,为什么呢?在数组中插入排序实现时会大量的移动数据从而删除位置不正确的元素,这是顺序表删除操作的低效性。从数学的角度,顺序表 (即数组)的删除操作是O(n).链表就不同,由于其存储位置的不固定性,其删除固定位置的元素只需要O(1)的时间,所以整体性能上获得比较大的提高。

 

3.编写实现数组排序的一种算法。说明为什么你会选择用这样的方法?

ANSWER 排序算法非常成熟了,实际上排序是研究算法的很有效例子。回答的时候尽量找一些比较有技术性的算法,比如堆排序或者快速排序,如果写冒泡什么的,别人都会 写,也就显示不出你的优秀了。当然一定要注意给定的条件。不至于三个数让你排序,你搞个快排,这就有点“宰牛刀杀鸡”了。

 

4.请编写能直接实现strstr()函数功能的代码。

ANSWER 首先要知道strstr()这个函数是干什么的,自己去查查C语言的书,一般附录后面会给出C语言标准库的。这个题目实际上也是一类重要的算法门类,叫做 “字符串的模式匹配”。它有很多的现成算法,其中最简单的要数朴素的匹配算法,还有KMP,BM这些高级算法,笔试估计是来不及写的。下面给出朴素的匹配 算法。

int stringMatching(char* pattern,char* text)

{

         int pLen = strlen(pattern),tLen = strlen(text);

         for(int i = 0;i <= tLen - pLen;i++){

      for(int j = 0; pattern[j] == text[i + j];j++);

                   if(j == pLen) return i;

         }

         return -1; // Not found

}

 

 

5.编写反转字符串的程序,要求优化速度、优化空间。

ANSWER:循环当然是最简单的。

void reverseString(char* str)

{

         int n = strlen(str);

         for(int i = 0;i < n/2;i++)

         {int t = str[i];str[i] = str[n - i - 1];str[n - i - 1] = t;}

}

 

6.在链表里如何发现循环链接?

ANSWER: 显然只需要判断是否存在回溯指针就行了。判断,是否存在某个节点的后继指向其前面位置的指针。具体实现的时候可以模仿DFS中的访问标志数组的方法,我们可以在struct node中设计该节点的一个访问标志位,设为visited 。每访问一个节点就将其visited域置为1。这样的话,一次遍历下来,如果发现某个后续节点的visited域已经是1,那么就可以判定其存在循环链接。具体的代码就不写了,太简单了。

bool findloop(node *head)

 { node *pf=head;

   node *ps=head->next;

   while(pf!=NULL&&ps!=NULL&&pf->next!=NULL&&ps->next!=NULL)

   { pf=pf->next;

     ps=ps->next->next;

     if(pf==ps)return true;

   }

return false;

 }


7.写一个函数,检查字符是否是整数,如果是,返回其整数值。(或者:怎样只用4行代码编写出一个从字符串到长整形的函数?)

分析 :简单!扫描一遍,每次生成对应整数的最高位。一行也就搞定了!

long convert(char* s_string,long s_integer)

{

for(int sLen = strlen(s_string), i = 0; i < sLen;s_integer += (s_string[i++] - '0')*pow(10,sLen - i - 1));

         return s_integer;

}

 

8.给出一个函数来输出一个字符串的所有排列。

ANSWER 简单的回溯就可以实现了。当然排列的产生也有很多种算法,去看看组合数学,还有逆序生成排列和一些不需要递归生成排列的方法。印象中Knuth的< TAOCP>第一卷里面深入讲了排列的生成。这些算法的理解需要一定的数学功底,也需要一定的灵感,有兴趣最好看看。

void permStr(char* str,int i)

{

         if(i == strlen(str) - 1)

           printf("%s\n",str);

         else

         {

            for(int j = i;j < strlen(str);j++)

            {

                      swap(&str[i],&str[j]);

                      permStr(str,i + 1);

                      swap(&str[i],&str[j]);

            }

         }

}

 

9.给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。

anSwer  记住,这种题目往往就是考你对边界的考虑情况。编程除了技术上的熟练以外,细心也是非常重要的。其实很多编程的大师可能并不是有特别的技术,往往就是他们 非常的耐心和细心,记住:编程是计算机科学中最基本的工作,它是最容易去掌握的,耐心点,细心点你一定能够学好它。代码看下面:

char* myStrcpy(char* s,char* a,char* b,char n)

{

int aLen = strlen(a),bLen = strlen(b);

         if(n > aLen || n > bLen)

                   return NULL; // Error

         for(int i = 0;i < aLen + bLen - n;i++)

                   if(i < aLen - n) s[i] = a[i];

                   else s[i] = b[i - aLen + n];

                   s[i] = '\0';

                   return s;

}

 

10.怎样编写一个程序,把一个有序整数数组放到二叉树中?

ANSWER :二叉搜索树的建树方法。简单的递归结构。实在不理解,干脆记下来好了。关于树的算法设计一定要联想到递归,因为树本身就是递归的定义。这里的递归应该是 理所当然的吧,不过,学会把递归改称非递归也是一种必要的技术。毕竟,递归会造成栈溢出,关于系统底层的程序中不到非不得以最好不要用。但是对某些数学问 题,就一定要学会用递归去解决。

void insertNode(bTree** root,int val)

{

    bTree* newNode = (bTree* ) malloc(sizeof(bTree));

         newNode->data = val;

        newNode->lChild = NULL;

        newNode->rChild = NULL;

      if(!(*root))

            *root = newNode;

    else if(newNode->data < (*root)->data)

          insertNode(&(*root)->lChild,val);

         else

          insertNode(&(*root)->rChild,val);  

}

 

11.怎样从顶部开始逐层打印二叉树结点数据?请编程。

ANSWER 二叉树的层次遍历没什么好说的,如果你不会还是早点把基础复习一下。一个劲的往后学,才会发现原来最最重要的还是以前最基础最简单的。

typedef struct myBinaryTree

{

         int data;

         struct myBinaryTree* lChild;

         struct myBinaryTree* rChild;

} bTree;

 

struct myQueen

{

         bTree* que[QSIZE];

         int front;

         int rear;

} binQueue; // Global var

 

void initQueue()

{

         // front == real makes the queue empty

         binQueue.rear = QSIZE - 1;

         binQueue.front = binQueue.rear;

         for(int i = 0;i < QSIZE;i++)

           binQueue.que[i] = NULL;

}

 

int enQueue(bTree* newNode)

{

         if(binQueue.front >= 1)

         binQueue.que[binQueue.front--] = newNode;

        

         else return 0;

         return 1;

}

 

bTree* deQueue()

{

         int t;

      if(binQueue.front != binQueue.rear){

         t = binQueue.rear;

         binQueue.rear--;

    return binQueue.que[t];

         }

         else return NULL;

}

int levelTraversal(bTree** root)

{

         initQueue();

         bTree* lc = (bTree* ) malloc(sizeof(bTree));

         bTree* rc = (bTree* ) malloc(sizeof(bTree));

         bTree* p = (bTree* ) malloc(sizeof(bTree));

         if((!lc) || (!rc) || (!p)){

         printf("OVERFLOW\n");

         exit(OVERFLOW); // Allocation Error

         }

         p = *root;

         if(!p) {

                   printf("Empty Tree,build it first !\n");

             return 0;

         }

         enQueue(p); // enqueue the root of the tree

      while (binQueue.front != binQueue.rear){

       p = deQueue();

            printf("%d ",p->data);

            lc = p->lChild;

            rc = p->rChild;

            if(lc != NULL)

                      enQueue(lc);

          if(rc != NULL)

                      enQueue(rc);

         }

         printf("\n");

         return 1;

}

 

12.怎样把一个链表掉个顺序(也就是反序,注意链表的边界条件并考虑空链表)?

ANSWER 前面说了,最基本的是最重要的。线性数据结构是学习数据结构的入门,一定要掌握好。微软的题目还是跟国内的公司不一样。国内的一上来就是些概念,跟考历史一样。

typedef struct listNode

{

         struct listNode* link;

         int data;

}node;

 

node* getNode(node* newNode,int val)

{

    if(!newNode)

                   exit(OVERFLOW);

         newNode->link = NULL;

         newNode->data = val;

         return newNode;

}

/*

  Insert a new node after p

*/

int insertNode(node* prev,node* newNode)

{

         if(!prev) return 0;

         newNode->link = prev->link;

         prev->link = newNode;

    return 1;

}

/*

 delete the node after the node prev

*/

int eraseNode(node*prev,node* p)

{

         if(p == NULL)

                   return 0;

         prev->link = p->link;

         free(p);

         return 1;

}

void buildList(node* head)

{

         int value;

         node* newNode = (node* ) malloc(sizeof(node));

         node* p = head;

         scanf("%d",&value);

         while(value != -1){

         newNode = getNode(newNode,value);

         insertNode(p,newNode);

         p = p->link;

         newNode = (node* ) malloc(sizeof(node));

         scanf("%d",&value);

         }

}

 

int reverseList(node* head)

{

         node* p = head->link;

         node* q = p->link;

         if(p == NULL){

         printf("The list is empty!\n");

         return 0;

         }

         while(q != NULL){

    node* newNode = (node* ) malloc(sizeof(node));

         newNode = getNode(newNode,q->data);

         insertNode(head,newNode);

         eraseNode(p,q);

         q = (node* ) malloc(sizeof(node)); // Allocate again

         q = p->link;

         }

         p->link = NULL;

      return 1;

}

http://blog.chinaunix.net/u2/76292/showart_1388527.html

posted on 2009-12-06 23:31 chatler 阅读(765) 评论(1)  编辑 收藏 引用 所属分类: Algorithm

FeedBack:
# re: 微软面试中简单的算法题目(转)
2009-12-06 23:33 | chatler
1.烧一根不均匀的绳子,从头烧到尾总共需要 1 个小时,问如何用烧绳子
的方法来确定半小时的时间呢?
2.10 个海盗抢到了100 颗宝石,每一颗都一样大小且价值连城。他们决定
这么分:
(1)抽签决定自己的号码(1~10);
(2)首先,由1 号提出分配方案,然后大家表决,当且仅当超过半数的人
同意时,按照他的方案进行分配,否则将被扔进大海喂鲨鱼;
(3)如果1 号死后,再由2 号提出分配方案,然后剩下的4 个人进行表决,
当且仅当超过半数的人同意时,按照他的方案进行分配,否则将被扔入大海喂鲨
鱼;
(4)依此类推??
条件:每个海盗都是很聪明的人,都能很理智地做出判断,从而做出选择。
问题:第一个海盗提出怎样的分配方案才能使自己的收益最大化?
3.为什么下水道的盖子是圆的?
4.中国有多少辆汽车?
5.你让工人为你工作7 天,回报是一根金条,这根金条平分成相连的7 段,
你必须在每天结束的时候给他们一段金条。如果只允许你两次把金条弄断,你如
何给你的工人付费?
6.有一辆火车以每小时15 公里的速度离开北京直奔广州,同时另一辆火车
以每小时20 公里的速度从广州开往北京。如果有一只鸟,以30 公里每小时的速
度和两辆火车同时启动,从北京出发,碰到另一辆车后就向相反的方向返回去飞,
就这样依次在两辆火车之间来回地飞,直到两辆火车相遇。请问,这只鸟共飞行
了多长的距离?
7.你有两个罐子以及50 个红色弹球和50 个蓝色弹球,随机选出一个罐子,
随机选出一个弹球放入罐子,怎样给出红色弹球最大的选中机会?在你的计划
里,得到红球的几率是多少?
8.想像你站在镜子前,请问,为什么镜子中的影像可以左右颠倒,却不能
上下颠倒呢?
9.如果你有无穷多的水,一个3 公升的提捅,一个5 公升的提捅,两只提
捅形状上下都不均匀,问你如何才能准确称出4 公升的水?
10.你有一桶果冻,其中有黄色、绿色、红色三种,闭上眼睛抓取同种颜色
的两个。抓取多少次就可以确定你肯定有两个同一颜色的果冻?
11.连续整数之和为1000 的共有几组?
12.从同一地点出发的相同型号的飞机,可是每架飞机装满油只能绕地球飞
半周,飞机之间可以加油,加完油的飞机必须回到起点。问至少要多少架次,才
能满足有一架绕地球一周。
参考答案:
1.两边一起烧。
2.96,0,1,0,1,0,1,0,1,0。
3.因为口是圆的。
4.很多。
5.分1,2,4。
6.6/7 北京到广州的距离。
7.100%。
8.平面镜成像原理(或者是“眼睛是左右长的”)。
9.3 先装满,倒在5 里,再把3 装满,倒进5 里。把5 里的水倒掉,把3 里
剩下的水倒进5 里,再把3 装满,倒进5 里,ok!
10.一次。
11.首先1000 为一个解。连续数的平均值设为x,1000 必须是x 的整数倍。
假如连续数的个数为偶数个,x 就不是整数了。x 的2 倍只能是5,25,125 才行。
因为平均值为12.5,要连续80 个达不到。125/2=62.5 是可以的。即62,63,61,
64,等等。连续数的个数为奇数时,平均值为整数。1000 为平均值的奇数倍。
1000=2×2×2×5×5×5;x 可以为2,4,8,40,200 排除后剩下40 和200 是
可以的。所以答案为平均值为62.5,40,200,1000 的4 组整数。
12.答案是5 架次。一般的解法可以分为如下两个部分:
(1)直线飞行
一架飞机载满油飞行距离为1,n 架飞机最远能飞多远?在不是兜圈没有迎
头接应的情况,这问题就是n 架飞机能飞多远?存在的极值问题是不要重复飞
行,比如两架飞机同时给一架飞机加油且同时飞回来即可认为是重复,或者换句
话说,离出发点越远,在飞的飞机就越少,这个极值条件是显然的,因为n 架飞
机带的油是一定的,如重复,则浪费的油就越多。比如最后肯定是只有一架飞机
全程飞行,注意“全程”这两个字,也就是不要重复的极值条件。如果是两架飞
机的话,肯定是一架给另一架加满油,并使剩下的油刚好能回去,就说第二架飞
机带的油耗在3 倍于从出发到加油的路程上,有三架飞机第三架带的油耗在5
倍于从出发到其加油的路程上,所以n 架飞机最远能飞行的距离为s=1+1/3+?
+1/(2n+1)这个级数是发散的,所以理论上只要飞机足够多最终可以使一架飞
机飞到无穷远,当然实际上不可能一架飞机在飞行1/(2n+1)时间内同时给n?1
个飞机加油。
(2)可以迎头接应加油
一架飞机载满油飞行距离为1/2,最少几架飞机能飞行距离1?也是根据不
要重复飞行的极值条件,得出最远处肯定是只有一架飞机飞行,这样得出由1/2
处对称两边1/4 肯定是一架飞机飞行,用上面的公式即可知道一边至少需要两架
飞机支持,(1/3+1/5)/2>1/4(左边除以2 是一架飞机飞行距离为1/2),但
是有一点点剩余,所以想像为一个滑轮(中间一个飞机是个绳子,两边两架飞机
是个棒)的话,可以滑动一点距离,就说加油地点可以在一定距离内变动(很容
易算出来每架飞机的加油地点和加油数量,等等)  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(10)

随笔分类(307)

随笔档案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感觉这个博客还是不错,虽然做的东西和我不大相关,觉得看看还是有好处的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新评论

阅读排行榜

评论排行榜