牛客题霸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]; } } } } }