概述
1.题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
2.算法描述
容易想到的思路1:可以以数字为键,数字出现的次数为值建立hash表,返回只出现一次的数。
容易想到的思路2:可以先排序整个数组,当一个数与前后都不同的时候就是只出现一次的数。
技术流思路如下:
考察异或操作。自己思考一下,就知道:
运算律:
x
异
或
x
=
0
,
x
异
或
0
=
x
red{x异或x=0,x异或0=x}
x异或x=0,x异或0=x
交换律:
x
异
或
y
异
或
z
=
x
异
或
z
异
或
y
red{x异或y异或z = x异或z异或y}
x异或y异或z=x异或z异或y
假设两个只出现一次的数是
x
,
y
x,y
x,y
1.初始化一个
t
e
m
p
=
0
temp=0
temp=0,与数组中的所有数字异或,其结果一定是
x
,
y
x,y
x,y异或的结果。(因为其他的数都是出现两次,并且异或满足交换律,两两抵消得0,且异或0是不变的)。
2.找到
t
e
m
p
temp
temp二进制中第一次出现
1
1
1的位置
i
d
x
idx
idx作为标准分割数组为两个子数组
1
,
2
1,2
1,2。那么
x
,
y
x,y
x,y就会被分别分到不同的子数组
1
,
2
1,2
1,2中。(因为
x
,
y
x,y
x,y的二进制第
i
d
x
idx
idx位一定是一个为
1
1
1,一个为
0
0
0)
3.则*子数组
1
1
1中元素全部异或得到
x
x
x,子数组
2
2
2中元素全部异或得到
y
y
y。
3.代码描述
3.1.Java代码
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array==null || array.length<2)
return;
int temp = 0;
for(int e: array){
temp ^= e;
}
int idxOf1 = findFirst1(temp);//找到temp最低位1的位置
for(int e: array){
if(isBit(e, idxOf1)==true)//为true 就是子数组1 为false就是子数组2
num1[0] ^= e;
else
num2[0] ^= e;
}
}
private int findFirst1(int temp){//找到数字中最低位的1的位置
int idx = 0;
while(((temp&1)==0)&&idx<32){
temp >>= 1;
idx++;
}
return idx;
}
private boolean isBit(int e, int idx){//判断e的第idx位是否是1
e = e>>idx;
return (e&1)==1;
}
}
3.2.Python代码
# -*- coding:utf-8 -*-
class Solution:
# 返回[a,b] 其中ab是出现一次的两个数字
def FindNumsAppearOnce(self, array):
ans = [0,0]
temp = 0
for e in array:
temp ^= e
idx = 0
while (temp&1)==0 and idx<32:
temp = temp>>1
idx+=1
for e in array:
if ((e>>idx)&1)==1:
ans[0]=ans[0]^e
else:
ans[1] = ans[1]^e
return ans
最后
以上就是复杂摩托为你收集整理的剑指Offer:数组中只出现一次的数字Java/Python1.题目描述2.算法描述3.代码描述的全部内容,希望文章能够帮你解决剑指Offer:数组中只出现一次的数字Java/Python1.题目描述2.算法描述3.代码描述所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复