剑指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  阅读(239)  评论(0编辑  收藏  举报