Single Number

来源:互联网 发布:倡导网络文明文章 编辑:程序博客网 时间:2024/06/06 01:13

Single Number I
Given an array of integers, every element appears twice except for one. Find that single one.

思路:只要将所有数组中的数组进行异或即可,因为相同两个数异或结果为0
代码如下:

public int singleNumber(int[] nums) {         int num = 0;        for(int i=0;i<nums.length;i++){            num ^= nums[i];        }        return num;    }

Single Number II
Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
对于这种问题,这里介绍一种万能的解法,以后看到这种在一个数组中多个数字出现n次,只有一个数字出现一次的这种题型,可以用这种解法:
思路:把所有整数看成32位的二进制数,统计该数组中每个数每个二进制位为“1”的个数,然后在对n取余,剩下的数如果不等于0,则是那个特殊数对应二进制的数,再将该数左移相应的位数,那么就得到该位对应“实际”的值,和以前的结果进行或运算,则得到的是自该位和该位以后“实际”的值。代码如下:

 public int singleNumber(int[] nums) {        int ans = 0;        for (int i = 0; i < 32; i++) {            int sum = 0;            for (int j = 0; j < nums.length; j++) {                if (((nums[j] >> i) & 1) == 1) {                    sum++;                }            }            sum %= 3;            if (sum != 0) {                ans |= sum << i;            }        }        return ans;    }

Single Number III
Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].
思路:首先将数组中所有数字进行异或,得到的是这两个数的异或结果,对结果进行分析,因为异或相同为0,不同为1,当异或结果中的某位出现1时,我们就可以断定,这两个数其中一个数的该位一定是1,另一个数的该位一定是0,于是我们就可以根据该位的数值对这个数组进行分组,分组后这两个数分别在这个两个数组内,然后用第一题的解法即可得到结果。
代码:

    public static int[] singleNumberII(int[] arr){        int A = 0;        int B = 0;        int result = singleNumber(arr);        //将结果转为2进制        String binResult = Integer.toString(result ,2);        //从后往前,找到哪个位置有1        int index = binResult.lastIndexOf("1");        //确定左移位数        int numShift = binResult.length() - index - 1;        for (int i : arr){            A = (((i >> numShift) & 1) == 1)? (A^i):A;//分组进行异或操作            B = (((i >> numShift) & 1) == 0)? (B^i):B;        }        return new int[]{A, B};    }

另一种方法,原理差不多:

public int[] singleNumber(int[] nums) {        int diff = 0;        for (int num : nums) {            diff ^= num;        }        diff &= -diff;//得到最后不同的一位,即找到“1”        int[] rets = {0, 0};        for (int num : nums) {            if ((num & diff) == 0) {                 rets[0] ^= num;            } else {                rets[1] ^= num;            }        }        return rets;    }