LeetCode 260. Single Number III

分析

难度 中
来源 https://leetcode.com/problems/single-number-iii/
两种方式,位运算或者利用HashSet

https://leetcode.com/problems/single-number-iii/discuss/68901/Sharing-explanation-of-the-solution
The two numbers that appear only once must differ at some bit, this is
how we can distinguish between them. Otherwise, they will be one of
the duplicate numbers. One important point is that by XORing all the
numbers, we actually get the XOR of the two target numbers (because
XORing two duplicate numbers always results in 0). Consider the XOR
result of the two target numbers; if some bit of the XOR result is 1,
it means that the two target numbers differ at that location. Let’s
say the at the ith bit, the two desired numbers differ from each
other. which means one number has bit i equaling: 0, the other number
has bit i equaling 1. Thus, all the numbers can be partitioned into
two groups according to their bits at location i. the first group
consists of all numbers whose bits at i is 0. the second group
consists of all numbers whose bits at i is 1. Notice that, if a
duplicate number has bit i as 0, then, two copies of it will belong to
the first group. Similarly, if a duplicate number has bit i as 1,
then, two copies of it will belong to the second group. by XoRing all
numbers in the first group, we can get the first number. by XoRing all
numbers in the second group, we can get the second number.

题目

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.
Example:
Input: [1,2,1,3,2,5]
Output: [3,5]
Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

解答

package LeetCode;

        import java.util.Arrays;
        import java.util.HashSet;
        import java.util.Iterator;

public class L260_SingleNumberIII {
    /*public int[] singleNumber(int[] nums) {
        if(nums.length<2)
            return nums;
        HashSet<Integer> hs=new HashSet<Integer>();
        for(int i=0;i<nums.length;i++){
            if(hs.contains(nums[i]))
                hs.remove(nums[i]);
            else
                hs.add(nums[i]);
        }
        Iterator<Integer>  it=hs.iterator();
        int[] result=new int[hs.size()];
        int i=0;
        while(it.hasNext()){
            result[i++]=it.next();
        }
        return result;
    }*/
    public int[] singleNumber(int[] nums) {//运行快,耗内存。
        int diff=0;
        for(int i=0;i<nums.length;i++)
        {
            diff^=nums[i];
        }
       /* System.out.println(Integer.toBinaryString(diff));
        System.out.println(Integer.toBinaryString(-diff));
        System.out.println(Integer.toBinaryString(diff&(-diff)));*/
        diff&=-diff;//此操作下最低的不同位为1,其余位为0.方便将数字分为两组
        int[] result={0,0};
        for(int i=0;i<nums.length;i++)
        {
            if((nums[i]&diff)==0){//不同位上为0的数字
                //System.out.println(Integer.toBinaryString(nums[i]));
                result[0]^=nums[i];
            }else{
                result[1]^=nums[i];//不同位上为1的数字
            }
        }
        return result;
    }
    public static void main(String[] args){
        L260_SingleNumberIII l260=new L260_SingleNumberIII();
        int[] nums={1,2,1,3,2,5};
        System.out.println(Arrays.toString(l260.singleNumber(nums)));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值