给出2n+1(2n+2)个数,其中有n个数是成对出现的,找出只出现一次的一个数/两个数
1 给出2n+1个数,其中有n个数是成对出现的,让我找出里面只出现了一次的那个数。
2 。给出2n+2个数,其中有n个数是成对出现的,让我找出里面只出现了一次的那两个数。
对于第一个问题我们用位运算来解决中的异或运算,注意异或运算的运算法则:相同为0,不同为本身
代码如下:
package yihuo;
public class yihuo {
public static void main(String[] args) {
// TODO Auto-generated method stub
int personal=0;
int personal1=0;
int a[]= {1,2,8,9,7,4,3,2,4,7,3,8,9,1,12};
for(int i=0;i<a.length;i++) {
personal=a[i]^personal;
}
System.out.println("出现了奇数次的那一个数 personal="+personal);
}
}
运行截图:
2 。给出2n+2个数,其中有n个数是成对出现的,让我找出里面只出现了一次的那两个数。
解题思路:因为是偶数个不同(以),所以异或运算之后得到的是两个不同元素的异或运算值,得不到想要的。但是如果我们把这一组数据分为两组,每一组分担一个不同的,分组异或运算之后,每一组就会把那个单一元素给找出来。
i.困难:在不知道的情况下,如何将N+2个数据划分为我们想要的两组。
ii.解决方法:将N+2个数据异或之后,将会得到我们想要的那两个值的异或值,得到的这个异或值,它的二进制中肯定有至少一位是1(因为不同),这里我们取最高位是1的那一位,将所有数据中对应位按照该位置上是0和1分开,分成两组,然后分组异或,将会得到两个值,就是我们想要的结果了。
如何得到异或值的二进制最高一位为1的位置呢,我用向左移动来实现。肯定有一个1,所以最坏情况是移动到最后成10000000,跳出循环。for(;p<127;) {//一直向左移动,找到personal1刚开始为1的位置也就是两个数不同的位置。 p=p<<1; youyicount++; }
每次记录向左移动次数,然后 location=8-youyicount;来得到那个位置。
为了在location位置上将所有数据分成两组,我想到0&n(任何数)都为0,1&n(n是1则1,n是0则0),所以将每个值和2的location-1次方做与运算,如果结果为零,说明该数据的二进制在location位置上为0,否则为1。根据0还是1得到两组
代码如下:
for(int i=0,j=0,m=0;i<b.length;i++) {
int t=b[i]&loc;
if(t==0) {
List1.add(b[i]);//两个唯一的数,在第Location位置上不同,所以按照Location位置
// 上0或1分为两组,可以将两个唯一值分开,分开后,按照上面的方法分别求即可
}else {
List2.add(b[i]);
}
}
得到两组后,就回到第一个问题了,想了好久,觉得可以,点赞支持一下哦
完整代码如下:
package yihuo;
import java.util.ArrayList;
public class yihuo {
// 给你n个数,其中有且仅有一个数出现了奇数次,其余的数都出现了偶数次。
// 用线性时间常数空间找出出现了奇数次的那一个数。
public static void main(String[] args) {
// TODO Auto-generated method stub
int personal1=0;
int location=0;
int loc;
int one=0;
int two=0;
int youyicount=0;
int b[]= {1,2,8,9,7,4,2,4,7,3,8,1,12,10,12,10,28,20,28,20};
ArrayList List1 = new ArrayList();
ArrayList List2 = new ArrayList();
for(int i=0;i<b.length;i++) {
personal1=b[i]^personal1;
}
System.out.println("将N+2N个数异或计算得到personal1="+personal1);
int p=personal1;
for(;p<127;) {//一直向左移动,找到personal1刚开始为1的位置也就是两个数不同的位置。
p=p<<1;
youyicount++;
}
location=8-youyicount;//位置
System.out.println("两个唯一值二进制不同的位置为 location="+location);
loc=(int) Math.pow(2,location-1);//根据得到的位置,获取需要的值
System.out.println("根据location得到关键值 loc="+loc);
for(int i=0,j=0,m=0;i<b.length;i++) {
int t=b[i]&loc;
if(t==0) {
List1.add(b[i]);//两个唯一的数,在第Location位置上不同,所以按照Location位置
// 上0或1分为两组,可以将两个唯一值分开,分开后,按照上面的方法分别求即可
}else {
List2.add(b[i]);
}
}
for(int i=0;i<List1.size();i++) {
int num=(int) List1.get(i);
one=(int)List1.get(i)^one;
}
for(int i=0;i<List2.size();i++) {
two=(int)List2.get(i)^two;
}
System.out.println("出现了奇数次的那一个数 one="+one);
System.out.println("出现了奇数次的那一个数 two="+two);
}
}
结果如图:
上一篇: 抖y账号密码加密算法
下一篇: 联合索引最左匹配原则
推荐阅读
-
给出2n+1(2n+2)个数,其中有n个数是成对出现的,找出只出现一次的一个数/两个数
-
2n+1个数中有2n个数出现过两次,找出其中只出现一次的数
-
给定一个非空整数数组,除了某个元素只出现一次之外,其余的都出现两次,找出只出现一次的那个数字
-
一组数中,只有两个数出现了一次,剩下的数都是成对出现,找出这两个数
-
一个数组中只有两个数字是出现一次,其他所有数字都出现了两次, 找出这两个只出现一次的数字。
-
一个数组中只有两个数字是出现一次的,其他的数字都出现了两次,找出这两个数字,编写程序。
-
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
-
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
-
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。...
-
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字