Single Number

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;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值