算法练习篇之:数组中只出现一次的数字

mac2024-11-24  40

算法练习篇之:数组中只出现一次的数字

题目描述解题思路代码实现总结

题目描述

一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。

解题思路

法一:大家都能想到的HashMap法 法二:异或法 方法一大家或许都可以想到,今天重点将方法二,题目中说明除了两个数字外,其余均为成对出现!!!通过观察我们可以发现成对出现的数字异或结果为零!这么一来思路或许开朗很多,假设数组中只有一个只出现一次的数字,那么我们对这个数组所有元素进行异或即可得出那个只出现一次的数字。那么下面的问题就变成,如何把这两个只出现一次的数字分到两个不同的数组中,然后两个数组分别异或即可求得这两个数字。我们知道对数组中元素进行异或结果为两个只出现一次的数字的异或结果,而这两个元素不相同,那么这两个元素异或结果至少存在一位不为零!!!在求得异或结果中第一位不为零的二进制结果索引后,我们通过对数组所有元素二进制对应索引是否为1,可分为两个子数组!然后依次对两个子数组求异或结果,即可得到两个只出现一次的数字。

结合代码多看两遍你就懂了!!!哈哈

代码实现

去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

import java.util.HashMap; public class findNumbersAppearOnce { //查找数组中只出现一次的数字 public void findAppearOnce_1(int[] array,int[] num1,int[] num2){ HashMap<Integer,Integer> temp=new HashMap<>(); for (int i=0;i<array.length;i++){ if (temp.containsKey(array[i])){ temp.remove(array[i]); }else { temp.put(array[i],1); } } int[] a=new int[array.length]; int i=0; for (Integer k:temp.keySet()){ a[i]=k; i++; } num1[0]=a[0]; num2[0]=a[1]; System.out.println(num1[0]+"......"+num2[0]); } public void findAppearOnce_2(int[] array,int[] num1,int[] num2){ if (array==null||array.length<2){ return; } int resultOR=0;//数组元素异或结果 for (int i=0;i<array.length;i++){//计算数组元素异或结果,为下面分出两个子数组做准备 resultOR^=array[i]; } int indexOR=findFirstBitIs1(resultOR); num1[0]=num2[0]=0; for (int j=0;j<array.length;j++){ if (IsBit1(array[j],indexOR)){ num1[0]^=array[j]; }else { num2[0]^=array[j]; } } System.out.println(num1[0]+"......"+num2[0]); } public int findFirstBitIs1(int num){//找过数组元素二进制异或结果中,第一位为1的索引,以此作为区分两个数组的依据 int index=0; while ((num&1)==0&&index<8){//对异或结果进行按位依次与运算找出第一个1的位置 num=num>>1; ++index; } return index; } public boolean IsBit1(int num,int indexOR){ num=num>>indexOR; return ((num&1)==1); } public static void main(String[] args) { findNumbersAppearOnce test=new findNumbersAppearOnce(); int[] array={2,4,3,6,3,2,5,5}; int[] num1=new int[array.length]; int[] num2=new int[array.length]; test.findAppearOnce_2(array,num1,num2); } }

总结

本题来源于面试经典教材《剑指offer》中 归属于位运算类型题目。 同许多在算法道路上不断前行的人一样,不断练习,修炼自己! 如有博客中存在的疑问或者建议,可以在下方留言一起交流,感谢各位! 最后,感谢AIAS!

觉得本博客有用的客官,可以给个赞鼓励下! 嘿嘿

最新回复(0)