您的位置:首页 > 编程语言

IT笔试编程部分复习

2014-05-15 14:59 169 查看
1.一个整形数组记录了1到n的所有整数,有且仅有一个缺省,找出缺省的这个数。

拿到这个题,会用很多想法,罗列几种。

(1)、在时间复杂度为O(N^2)的情况下用双重循环找出,空间复杂度为O(N)。

(2)、用哈希法,时间复杂度为O(N),需额外空间,空间复杂度为O(N)。

(3)、先求出1到n的累加和,然后减去数组中所有数的累加和,得所求。时间复杂度为O(N),不需额外空间。

(4)、先求出1到n的异或和,然后再跟数组中所有数的异或和,得所求。时间复杂度为O(N),不需额外空间,由于异或运算由于加法运算,所以方法4更高效。

#include<iostream>

using namespace std;

//亦或

int find_That_One1(int da[],int n,int up)

{

int sum=0;

for(int i=1;i<=up;i++)

sum^=i;

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

sum^=da[i];

return sum;

}

//加法

int find_That_One2(int da[],int n,int up)

{

int sum=(1+up)*up/2;

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

sum-=da[i];

return sum;

}

//哈希法

int find_That_One3(int da[],int n,int up)

{

int *tmpData=new int[up+10];

memset(tmpData,-1,sizeof(int)*up+10);

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

tmpData[da[i]]=0;

for(int i=1;i<=up;i++)

if(-1==tmpData[i])

return i;

}

int main()

{

int data[11]={1,2,3,5,6,7,8,9,10,11,4};

cout<<find_That_One1(data,11,12)<<endl;

cout<<find_That_One2(data,11,12)<<endl;

cout<<find_That_One3(data,11,12)<<endl;

system("pause");

}

2.一个整形数组除一个数只出现一次外,其余的都出现2次,求这个数。

这里的一次可以改成奇数次,2次可以改成偶数次。这是个抑或运算的典型试题,将所有数进行异或运算即得所求。
#include<iostream>

using namespace std;

int find_One(int da[],int n)

{

int sum=0;

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

sum^=da[i];

return sum;

}

int main()

{

int data[11]={1,2,4,6,7,2,9,1,4,7,6};

cout<<find_One(data,11)<<endl;

system("pause");

}

3.一个整形数组除两个数只出现一次外,其余的都出现2次,求这两个数。

这是个抑或运算的典型试题,将所有数进行异或运算即得所求。由于出现一次的数不相同,所以其异或值不为0,。可以根据其中某一位为1将这两个数分到不同的组中,然后用方法2求解。异或值在某位为1对应那两个数在该位上不相等,自然想到分组。我选用确定最右边为0位,a&(~a+1).
#include<iostream>

using namespace std;

int find_One(int da[],int n)

{

int sum=0;

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

sum^=da[i];

return sum;

}

int low_Bit(int a)

{

return a&(~a+1);

}

int find_Two(int da[],int n)

{

int sum=0;

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

sum^=da[i];

int lowBit=low_Bit(sum);

int tmp;

int j=n-1;

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

{

if(low_Bit(da[i])==lowBit)

{

tmp=da[j];

da[j]=da[i];

da[i]=tmp;

i--;

j--;

if(j<0)break;

}

}

return j;

}

int main()

{

int data[10]={10001,599,123133554,123456,599,354,77777,123456,354,10001};

int n=find_Two(data,10);

cout<<find_One(data,n+1)<<" "<<find_One(data+n+1,10-n-1)<<endl;

system("pause");

}

4.一个整形数组除3个数只出现一次外,其余的都出现2次,求这3个数。

3个数应该想法设法转化成2个数,然后求解。可以先求出所有数的异或值sum,即3个只出现1次的不相同的数的异或值。假设3个数为a,b,c。然后将sum与所有的数进行异或运算,得b^c,a^c,a^c。由于b^c,a^c,a^c3个新数的异或值为0,且两两互不相等同时不为0。所以必定存在在某些位上两个位1,拎一个为0,可以据此求出一个,进而转化成问题3.为了方便,首先考虑最低位。

#include<iostream>

using namespace std;

int find_One(int da[],int n)

{

int sum=0;

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

sum^=da[i];

return sum;

}

int low_Bit(int a)

{

return a&(~a+1);

}

int find_Two(int da[],int n)

{

int sum=0;

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

sum^=da[i];

int lowBit=low_Bit(sum);

int tmp;

int j=n-1;

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

{

if(low_Bit(da[i])==lowBit)

{

tmp=da[j];

da[j]=da[i];

da[i]=tmp;

i--;

j--;

if(j<0)break;

}

}

return j;

}

void find_There(int da[],int n)

{

int sum=0;

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

sum^=da[i];

int dif=0;//2个最低位为1,一个为0,dif为那个数的最低位

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

dif^=low_Bit(da[i]^sum);

int weWant=0;//找出那个数

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

if(low_Bit(da[i]^sum)==dif)

weWant^=da[i];

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

{

if(weWant==da[i])

{

int tmp=da[n-1];

da[n-1]=da[i];

da[i]=tmp;

}

}

cout<<weWant<<" ";

int m=find_Two(da,n-1);

cout<<find_One(da,m+1)<<" "<<find_One(da+m+1,n-1-m-1)<<endl;

}

int main()

{

int data[11]={10001,599,123133554,123456,599,354,77777,123456,354,10001,4};

find_There(data,11);

system("pause");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: