1 package com.yan.offer; 2 3 /** 4 * 题目描述: 5 * 6 * 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 7 * 8 * @author Yan 9 *10 */11 public class ArrayFindSingleNum {12 13 public ArrayFindSingleNum() {14 }15 16 private static int[] arr = new int[] { 2, 4, 3, 6, 3, 2, 5, 5 };17 18 public static void main(String[] args) {19 ArrayFindSingleNum arrayFindNum = new ArrayFindSingleNum();20 int[] num1 = new int[1];21 int[] num2 = new int[1];22 arrayFindNum.findNumsAppearOnce(arr, num1, num2);23 System.out.println(num1[0] + " " + num2[0]);24 }25 26 // num1,num2分别为长度为1的数组。传出参数27 // 将num1[0],num2[0]设置为返回结果28 public void findNumsAppearOnce(int[] array, int[] num1, int[] num2) {29 if (array == null || array.length == 0 || array.length == 1) {30 return;31 }32 int sum = 0;33 // 将数组中所有元素进行异或。34 for (int i = 0; i < array.length; i++) {35 sum ^= array[i];36 }37 int temp = sum;38 int flag = 1;39 // 判断异或结果中低位起第一个为1的位,即为flag为1的位。40 while (true) {41 if ((temp & flag) != 0) {42 break;43 } else {44 flag = flag << 1;45 }46 }47 int sum1 = 0;48 int sum2 = 0;49 // 利用为1的位将数组中的元素分为两部分,一部分为该位为0的元素,另一部分为该位为1的元素。50 // 因为不相同的两个数的异或值中该位为1,所以这两个数该位是不同的,所以这两个数就被分到了两个不同的部分。51 // 因此,分别将每一部分进行全部异或,最终得到的结果分别为两个不相同的数。52 for (int i = 0; i < array.length; i++) {53 if ((array[i] & flag) != 0) {54 sum1 ^= array[i];55 } else {56 sum2 ^= array[i];57 }58 }59 num1[0] = sum1;60 num2[0] = sum2;61 62 }63 64 }