您现在的位置是:主页 > news > 中国专业做鞋子的网站/推广seo网站
中国专业做鞋子的网站/推广seo网站
admin2025/5/11 23:30:56【news】
简介中国专业做鞋子的网站,推广seo网站,网站开发职业认知小结,成都市房产管理局官网题:假设你有一个用1001个整数组成的数组,这些整数是任意排列的,但是你知道所有的整数都在1到1000(包括1000)之间。此外,除一个数字出现两次外,其他所有数字只出现一次。假设你只能对这个数组做一次处理,用一…
题:假设你有一个用1001个整数组成的数组,这些整数是任意排列的,但是你知道所有的整数都在1到1000(包括1000)之间。此外,除一个数字出现两次外,其他所有数字只出现一次。假设你只能对这个数组做一次处理,用一种算法找出重复的那个数字。如果你在运算中使用了辅助的存储方式,那么你能找到不用这种方式的算法吗?
方法一、使用辅助的存储方式,该选择何种存储方式呢?可使用hash的存储方式,以1到1000作为hash表的索引,遍历原数组,统计各数字出现的个数并存储到以该数字为索引值的hash表中,若某个hash[x]的值为2则退出循环,x就是重复出现两次的数字。时间复杂度最坏是O(n)。优点:高效率,缺点:消耗的内存空间过大。
代码如下所示:
int hash[7]={0}; for(int i=0;i<7;++i){ if(++hash[a[i]]==2){ cout<<"result:"<<a[i]; break; } }
这个方法是本人认为解这里问题的比较好的一种方法,对于问题的变形也具有一定的鲁棒性。比如题目改变成:在一个数组中有1000个数字,数字范围是1到1000,其中只有一个是重复的剩下的都不重复。
方法二,采用异或的方式来求取
思想:1001个数异或结果与1-1000异或的结果再做异或,得出的值即位所求。
原理:
设重复数为A,其余999个数异或结果为B。1001个数异或结果为A^A^B。1-1000异或结果为A^B。由于异或满足交换律和结合律,
则有 (A^B)^(A^A^B)=A^B^B=A
代码如下:
int a[7]={1,4,5,6,2,3,5};int i=0,j=0;int b[6]={1,4,6,2,3,5};int temp=a[0];for(i=1;i<7;++i){temp=temp^a[i];}int temp2=b[0];for(j=1;j<6;++j){temp2=temp2^a[j];}int result = temp^temp2;cout<<"result:"<<result;
用异或的方法解决此类问题可扩展性也非常好,比如,当题目变形为:在一个数组中只有一个数是不重复的剩余的数都出现了两次,现在求不重复的那个数。
思路:异或中两个相同的数相异或结果为0,0与其他数异或都是其他数。代码如下:
int a[5]={5,4,5,1,4}; int i=0,j=0; int temp=a[0]; for(i=1;i<5;++i){ temp=temp^a[i]; } cout<<"result:"<<temp;
方法三,求和法
这个是完全的数学思想的一种方法:想将原数组S1的所有元素的加起来,然后再将S2={1,2,...,1000}折1000个数的所有元素加起来,最后做减法就能得到出现仅两次的那个数了。
但是这个方法的局限性很强,比如将题目变形一下:在一个数组中有1000个数字,数字范围是1到1000,其中只有一个是重复的剩下的都不重复(也就是在这1000个数据中有一个数出现了两次,有一个数一次都没出现),若是求那个重复的数字是多少?此时用这个方法就行不通了。此时使用方法一能够解决。
若是求那个没出现的数字是多少,就需要方法一和方法三合作求出了。先用方法一求出重复的数字x,然后sum(s2)-(sum(s1)-x);其中s1是输入的数组,s2是1到1000的数组。
这个题目只是这类题目中的一个,变形的有很多。