牛客题霸NC75数组中只出现一次的数字Java题解
https://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?tpId=117&&tqId=34997&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking
方法1:分组异或
解题思路:先将数组中所有的数做异或(相同为0,相异为1),可以得到这两个不相同数的异或。对于异或后的结果(二进制)从右往左数一定有一位为1,这一位就可以用来区分这两个不相同的数。利用mask获得异或结果中最低的一位1,这样就可以进行分组,然后这两个不同的数一定会被分到不同的组中,其他相同的数一定会被分到同组,再对同组内做异或,就可以得到这两个不同的数了。
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int k = 0;
for(int num: array) { //将所有的数做异或
k ^= num;
}
int mask = 1;
//获取mask,用于分组( 获得k中最低位的1(可以区分两个不同数的那一位))
while((k & mask) == 0) {
mask <<= 1;
}
for(int num: array) { //分组
if((num & mask) == 0) {
num1[0] ^= num; //组内做异或
} else {
num2[0] ^= num; //组内做异或
}
}
}
}方法2:HashMap
解题思路:利用HashMap存储数组中每个数字及出现的次数,再通过遍历数组和HashMap查找出出现次数为1的两个数。
import java.util.*;
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
HashMap<Integer,Integer> map = new HashMap<>(); //利用HashMap存储数组中每个数字及出现的次数
for(int i = 0;i<array.length;i++){ //将数组中的值和出现次数保存到HashMap中
if(map.containsKey(array[i])){
map.put(array[i],2);
}else{
map.put(array[i],1);
}
}
boolean flag = false; //设置标志,如果遍历出次数为1的数,就将其设为true
for(int j=0;j<array.length;j++){ //遍历数组array
if(map.get(array[j])==1){ //如果当前数字出现的次数为1
if(flag==false){ //如果之前没出现过次数为1的数,则将其保存到num1[0]中
num1[0] = array[j];
flag = true;
}else{ //如果已经出现过次数为1的数,则将其保存到num2[0]中
num2[0] = array[j];
}
}
}
}
}
京公网安备 11010502036488号