几道经典的面试题

1、怎么判断链表里有没有环?

这个题目网上,书上都有答案。设置两个指针,刚开始都指向链表的头部,然后一个指针一次跑一步,另一个指针一次跑两步,每移动一次就判断他们是不是相等,如果相当,则链表中有环,并且交点就在现在两个指针所指的位置。

但是如果事先没有看到这个解答,在面试官面前能不能回答回来呢?

当然此题也可以用一个指针,再用一个足够大的数组把指针所遍历的结点的地址都保存起来,并且指针每移动一步就在数组中查找是否有和指针当前存储的地址相等的值。如果数组中存在一个地址和指针当前存储的地址相等,那么结点之前已经遍历过了,指针所指向的当前结点即为链表交叉的地方。

2、一个单向链表,遍历一次且最多只能遍历一次,要找出倒数第N个的结点。

定义两个指针,当其中一个指针向后移动N个结点后,第二个指针才开始向后移动。当第一个指针到达链表的末尾时,第二个指针就指向了倒数第N个结点了。

3、1条直线把平面分成2个区域,2条直线把平面分成4个区域,3条直线把平面分成7个区域,这样依次每加一条直线都把平面分成最多的区域。问加入第2000条直线后,平面被分成了多少个区域?

这个题目也是个很经典的题目,有些书也有解答。不过看到这种题目,第一反应就是:肯定是有规律的,不然根本无法求解的。怎么找规律呢?那肯定是先从最边界(特殊)的情况开始研究,然后推广到一般的情况去。也就是把1条直线,2条直线,3条直线把平面都分成了多少个区域都找出来,然后推出规律,并验证。

这个题目,确实是要从最简单的情况开始分析。通过细心的观察,你可以发现,每加入一条直线,都会把原来的已经被切开的平面再切成2份,一份所包含的区域数就是加入直线前的区域数,另一份所包含的区域数就是就是原来已有的直线数再加一,即加入第几条直线,就会增加几个区域。第2000条直线也就会增加2000个区域。

4、给定一个正整数,写一个程序判断把它转换为2进制数后,2进制数里有多少个1。要求效率尽可能的高。

这题如果按照最常规的方法来做的话,比把一个数转化为2进制数还要简单。但是听说能用位运算的话,效率更高。研究了一下,代码如下:

[csharp] view plain copy
  1. #include <iostream></iostream>  
  2. using namespace std;  
  3.   
  4. int main()  
  5. {  
  6.     int n;  
  7.     int cnt = 0;  
  8.     while (cin >> n) { // n为正整数。  
  9.         while (n) {  
  10.             if (n & 1)  
  11.                 ++cnt;  
  12.             n = n >> 1;  
  13.         }  
  14.         cout << cnt << endl;  
  15.         cnt = 0;  
  16.     }  
  17.       
  18.     return 0;  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值