> 文档中心 > 一个C语言面试的经典例题

一个C语言面试的经典例题

前言:这个题目是C语言面试题中非常经典的一道题目,当你面对这道题目是不是有点思路,然后到中间就断了?没错我第一次遇到的时候,也是卡在中间了,现在写下这篇博客为了更加的理清思路,加深印象!!!

题目:一个整型数组num里两个数字之外出现一次,其他数字都出现了两次。请写程序找出这两个只出现一次的数字,要求时间复杂度为O(n),空间复杂度为O(1);例如数组为{1,3,5,7,1,3,5,9},找出7和9

注:时间复杂度:不是计算时间,是计算大概的运算次数
       空间复杂度:不是计算空间,是计算大概定义的变量个数;O(1)代表定义常数个变量,并不是单只1个。

解析:当拿到这个题目,第一感觉肯定是要用异或运算符,但是异或完以后呢?出现两次的都异或为0了;只剩下两个只出现一次的数字;怎么把这两个数字分开呢?这就是难点,方法很巧妙,很难想出来!!!所以我不妨先写简单一点的,假如这个题目只有一个出现一次的数字,怎么把它取出来?

更改后的题目:一个整型数组num里除一个数字之外出现一次,其他数字都出现了两次。请写程序找出这一个只出现一次的数字,要求时间复杂度为O(n),空间复杂度为O(1)

   这样就很简单了,在输入整个数组的数后;直接定义一个变量(暂定为n=0);遍历整个数组,然后开始从第一个数组元素与n进行异或操作,最终结果就是我们想要的值!!!

下面看具体代码:

 注意:

1. define定义的是标识符常量;数组我们就暂时定义为20个整型的大小;想要输入几个数,由我们自己决定;

2. ^是按位异或;相同为0,相异为1;0与任何数异或还是任何数它本身;我们遍历整个数组,都要异或一遍。

    好了,简单的只有一个数出现一次的,我们已经解决了,现在来解决有两个数出现一次的;假如这两个数是a=5和b=6,那么整个数组异或的结果就是:m=a^b=5^6;最终异或的结果就是:

 那么我们怎么把这两个数分开呢?我们发现最终结果m的二进制位有0有1;那就找m的任何一个二进制位为1的数来作为划分;为什么?

答:因为当m的一个二进制数为1时,必然是这两个异或的数(a和b)对应的位数一个是0一个是1,才可能异或成结果为1的二进制位;所以,通过这个方法就能把他们分离开来。

有了这个思路,我们还有两个问题要解决:1.怎么求出一个数的位为1的下标?

                                                                    2.分开的两组数据,怎么办?在创建两个数组存起来?

1.怎么求出一个数的二进制位为1的下标?

 这就需要另外一个知识点,比如我用的是VS2019(32位);我们就要写一个循环,取出它的每一个二进制位与1相与,这样就能把一个数的每一个二进制位为1的位取出来;下面看具体事例:

注:怎么取出每一位?假如这个数是5;对于32位机器,它的二进制表示是

00000000 00000000 00000000 00000101    我们可以把这个数利用左移操作符(>>)来取出它的每一个二进制位:

第一次不移位,看第一位是不是为1;

第二次移1位看第二位是不是1.........

直到移了第31位,就能让最后第32位的二进制取出来与1相与看是不是1

具体代码如下:

          当然在这个题目中我们只需要从数中找到一个二进制位为1的,所以找到一个后,我们就定义一个变量(暂定这个变量为pos, pos = i)来记住移了多少位,在break跳出循环;详细理解看下面:

2.分开的两组数据,怎么办?在创建两个数组存起来?

     分为两组数以后,怎么办呢?在用两个数组存起来?然后继续按照一个数字出现一次,其它数字都是出现两次的情况来处理?=====》想想都麻烦

答:我们在利用pos这个下标分组前,就先定义两个变量用来接收最后两边分组过后最终剩下的两个只出现一次的数(暂定两个变量为m1, n1);重新遍历整个数组,开始每个数左移pos位与1相&;最终分为两组=========>pos位为1的分为一组,pos位为0的分为一组;在每一组每添加一个新成员,就与m1或者n1进行异或,直到最终每一组所有成员都添加进来,异或结束,两个组剩的最后数值就是对应的两个只出现一次的数!!!

下面看具体实现代码:

随便举一组数,进行验证:

总结: 你也可以在定义时,就把数组的大小和元素的初始值都初始化上,这样就会直接输入最终的两个元素,看着界面比较干净美观;但是这样的代码并不通用,相当于写死了,换一组数据改着太麻烦;所以我更喜欢这种灵活的方式。

      刚开始写可能有些表述不清楚,遇到看不懂的可以先结合下面的代码结合着看;有错误可以及时留言告诉我,一起学习,一起进步!!!

央视天气网