题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
方法一:
思路,使用一个HashMap,key为数组中的数字,value为出现次数,遍历一遍构建HashMap,然后再遍历一遍HashMap,找到value值为1的key。时间复杂度O(n),空间复杂度O(n)
知识点:HashMap的定义,判断某个对象是否是hashMap的key,get,put,遍历HashMaP
代码:
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
import java.util.HashMap;
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
HashMap<Integer,Integer> hashMap = new HashMap<>();
boolean flag = true;
for(int i=0;i<array.length;i++){
if(!hashMap.containsKey(array[i])){
hashMap.put(array[i],0);
}else{
hashMap.put(array[i],1);
}
}
for(int key:hashMap.keySet()){
if(hashMap.get(key) == 0){
if(flag){
num1[0] = key;
flag = false;
}else{
num2[0] = key;
}
}
}
}
}
方法二:
思路:先遍历一遍数组,将数组中每个数字进行异或操作,结果就是两个只出现一次的数字异或的结果。因为这两个数字不同,所以结果一定不为0。找到右边第一个此不为0的位数(看找的函数,就可以发现,找右边的简单)。那这两个数字,一定一个这位为0,一个不为0,按这个标准,将数组分为两部分,在两部分中分别遍历,将其异或,由于相同的数字异或结果为0,所以最总结果一定为这两个数字。时间复杂度O(n),空间复杂度O(1)。优于方法1.
知识点:位运算,异或运算,如何得到一个int型变量某位上的值(右移)
代码:
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
import java.util.HashMap;
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array == null || array.length<2) return;
int num = 0;
for(int i=0;i<array.length;i++){
num = num ^ array[i];
}
int leftFirstNot0 = getLeftFirstNot0(num);
for(int i=0;i<array.length;i++){
if(isLeft0(array[i],leftFirstNot0)){
num1[0] = num1[0] ^ array[i];
}else{
num2[0] = num2[0] ^ array[i];
}
}
}
public int getLeftFirstNot0(int num){
int index = 0;
while((num & 1) == 0){
num = num >>> 1;
++index;
}
return index;
}
public boolean isLeft0(int num,int index){
return (num>>>index & 1) == 1 ;
}
}