剑指offer第40题
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 }
posted on 2016-06-21 20:54 Yanspecial 阅读(241) 评论(0) 编辑 收藏 举报