Problem:

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].

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?

Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.

Analysis:

Sort a array is always a good beginning to find duplciates in a array.
But it would at least take O(nlogn) time in sorting the array. Solution 1:
Basic idea:
step 1: sort the entire array.
step 2: in the sorted form, if a element does not have neighors share the same value wit it. It must be the single element we want to find.
Note: take care the first and last element, it may incure out of bound exception. public int[] singleNumber(int[] nums) {
if (nums == null || nums.length <= 1)
return new int[0];
Arrays.sort(nums);
int[] ret = new int[2];
int count = 0;
for (int i = 0; i < nums.length; i++) {
boolean is_single = true;
if (i != 0)
is_single = is_single && (nums[i] != nums[i-1]);
if (i != nums.length - 1)
is_single = is_single && (nums[i] != nums[i+1]);
if (is_single)
ret[count++] = nums[i];
}
return ret;
} Wrong logic:
If you use the default value of flag as "true", you must take care the logic you are going to implment. (|| or &&)
Initially, I have implemented following problemetic logic
-------------------------------------------------------------------
for (int i = 0; i < nums.length; i++) {
boolean is_single = true;
if (i != 0)
is_single = is_single || (nums[i] != nums[i-1]);
if (i != nums.length - 1)
is_single = is_single || (nums[i] != nums[i+1]);
if (is_single) {
ret[count] = nums[i];
count++;
}
}
------------------------------------------------------------------- In the above code, the is_single would alway be true, since the intial default is true and I use "||" to pass around logic.
What I meant to do is "once it has a neighor, it should return false, and pass to the value".
The change is easy:
is_single = is_single && (nums[i] != nums[i-1]); Even though the above solution is clear, there could a very elegant and genius solution for this problem.
But it requires strong understand of bit operation.
Key:
The magic rule of XOR.
a ^ a = 0;
a ^ b ^ a = 0;
a ^ b ^ c ^ a = b ^ c;
After the XOR operation, all numbers appear even times, would be removed from the final XOR value.
What's more, after "a ^ b ^ c ^ a = b ^ c", the set bits of "b ^ c" would only contain the digits that b are different from c. Solving step:
step 1: XOR all elements in the array. int xor = 0;
for (int i = 0; i < nums.length; i++) {
xor ^= nums[i];
} step 2: get the rightmost bit of the set bit.
right_most_bit = xor & (~(xor-1)); step 3: divide the nums array into two set based on the set bit. (thus the single numbers: b, c would be placed into two different set). Then XOR at each set and get those two numbers.
for (int i = 0; i < nums.length; i++) {
if ((nums[i] & right_most_bit) == 0) {
ret[0] ^= nums[i];
} else{
ret[1] ^= nums[i];
}
} Skills:
1. how to get the rightmost set bit?
right_most_bit = xor & (~(xor-1));
Reason:
The xor-1 would turn the rightmost set bit into 0, and bits after it becomes 1.
'1000001000' => '1000000111'
The not "~" operation would turn all bits into opposite bit (note the rightmost bitset has already been setted into 0)
'1000000111' => '0111111000'
The '&' operation would filter the setbit out.
'0111111000'
'1000001000'
'0000001000' 2. The set bit could be used a proper indicator to divide the original array into two sets.
if ((nums[i] & right_most_bit) == 0) {
ret[0] ^= nums[i];
} else{
ret[1] ^= nums[i];
}
Note the form of set bit: '0000001000', only the number share the same bit would not equal to "000000000...(integer: 0)"

Solution:

public class Solution {
public int[] singleNumber(int[] nums) {
if (nums == null || nums.length == 0)
return new int[0];
int[] ret = new int[2];
int xor = 0, right_most_bit = 0;
for (int i = 0; i < nums.length; i++) {
xor ^= nums[i];
}
right_most_bit = xor & (~(xor-1));
for (int i = 0; i < nums.length; i++) {
if ((nums[i] & right_most_bit) == 0) {
ret[0] ^= nums[i];
} else{
ret[1] ^= nums[i];
}
}
return ret;
}
}

[LeetCode#260]Single Number III的更多相关文章

  1. LeetCode 260. Single Number III(只出现一次的数字 III)

    LeetCode 260. Single Number III(只出现一次的数字 III)

  2. [LeetCode] 260. Single Number III 单独数 III

    Given an array of numbers nums, in which exactly two elements appear only once and all the other ele ...

  3. Java [Leetcode 260]Single Number III

    题目描述: Given an array of numbers nums, in which exactly two elements appear only once and all the oth ...

  4. LeetCode 260 Single Number III 数组中除了两个数外,其他的数都出现了两次,找出这两个只出现一次的数

    Given an array of numbers nums, in which exactly two elements appear only once and all the other ele ...

  5. Leetcode 260 Single Number III 亦或

    在一个数组中找出两个不同的仅出现一次的数(其他数字出现两次) 同样用亦或来解决(参考编程之美的1.5) 先去取出总亦或值 然后分类,在最后一位出现1的数位上分类成 ans[0]和ans[1] a&am ...

  6. [LeetCode] 260. Single Number III(位操作)

    传送门 Description Given an array of numbers nums, in which exactly two elements appear only once and a ...

  7. leetcode 136 Single Number, 260 Single Number III

    leetcode 136. Single Number Given an array of integers, every element appears twice except for one. ...

  8. leetcode 136. Single Number 、 137. Single Number II 、 260. Single Number III(剑指offer40 数组中只出现一次的数字)

    136. Single Number 除了一个数字,其他数字都出现了两遍. 用亦或解决,亦或的特点:1.相同的数结果为0,不同的数结果为1 2.与自己亦或为0,与0亦或为原来的数 class Solu ...

  9. 【刷题-LeeetCode】260. Single Number III

    Single Number III Given an array of numbers nums, in which exactly two elements appear only once and ...

随机推荐

  1. C#中的static静态变量的用法

    静态全局变量 定义:在全局变量前,加上关键字 static 该变量就被定义成为了一个静态全局变量. 特点: A.该变量在全局数据区分配内存. B.初始化:如果不显式初始化,那么将被隐式初始化为0. 静 ...

  2. vue写请求接口--请求参数的变量要在return里面声明

    //谨记return里面是返回所有声明的变量的名字,数组以及对象等等 export default { data () { return { //所有的变量都是写在data 的return里面的,主要 ...

  3. (转)php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法

    php 获取今日.昨日.上周.本月的起始时间戳和结束时间戳的方法,主要使用到了 php 的时间函数 mktime. 下面首先还是直奔主题以示例说明如何使用 mktime 获取今日.昨日.上周.本月的起 ...

  4. 自定义组合控件,适配器原理-Day31

    自定义组合控件,适配器原理-Day31 mobile2.1 主页定义 手机上锁功能 1.弹出设置密码框. 手机下载进度 自定定义控件 控件的属性其实就是控件类一个属性设置属性调用类的set方法方法, ...

  5. LINUX nohup命令输入输出深浅进出

    无论是否将 nohup命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中.如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中 ...

  6. MyBatis的学习总结六:Mybatis的缓存【参考】

    一.Mybatis缓存介绍 正如大多数持久层框架一样,Mybatis同样提供了一级缓存和二级缓存 1.一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Session, ...

  7. React初探

    经过几天根据官方文档和博园中一些大牛的文章,在了解过基础的语法和组件后,总结一下: 1.第一件事就是分析界面,理想状态下是让每个组件只做一件事情,也就是单一职责,相互嵌套.我认为: 构建组件树,整体的 ...

  8. mysql主要应用场景 转载

    前言 据说目前MySQL用户已经达千万级别了,其中不乏企业级用户.可以说是目前最为流行的开源数据库管理系统软件了.任何产品都不可能是万能的,也不可能适用于所有的应用场景.那么MySQL到底在什么场景下 ...

  9. URL 路由访问报错

    错误: 错误分析:    控制器的文件名命名有问题(index.php)    在TP中控制器命名规范(IndexController.class.php) 相信许多PHP开发者在使用ThinkPHP ...

  10. [转] CSS direction属性简介与实际应用 ---张鑫旭

    一.用的少并不代表没有用 至少,在我接触的这么多项目里,没有见到使用过CSS direction属性做实际开发的. 为什么呢?是因为direction长得丑吗? 虽然说direction确实其貌不扬, ...