[LeetCode#260]Single Number III
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:
- The order of the result is not important. So in the above example,
[5, 3]is also correct. - 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的更多相关文章
- LeetCode 260. Single Number III(只出现一次的数字 III)
LeetCode 260. Single Number III(只出现一次的数字 III)
- [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 ...
- Java [Leetcode 260]Single Number III
题目描述: Given an array of numbers nums, in which exactly two elements appear only once and all the oth ...
- LeetCode 260 Single Number III 数组中除了两个数外,其他的数都出现了两次,找出这两个只出现一次的数
Given an array of numbers nums, in which exactly two elements appear only once and all the other ele ...
- Leetcode 260 Single Number III 亦或
在一个数组中找出两个不同的仅出现一次的数(其他数字出现两次) 同样用亦或来解决(参考编程之美的1.5) 先去取出总亦或值 然后分类,在最后一位出现1的数位上分类成 ans[0]和ans[1] a&am ...
- [LeetCode] 260. Single Number III(位操作)
传送门 Description Given an array of numbers nums, in which exactly two elements appear only once and a ...
- leetcode 136 Single Number, 260 Single Number III
leetcode 136. Single Number Given an array of integers, every element appears twice except for one. ...
- leetcode 136. Single Number 、 137. Single Number II 、 260. Single Number III(剑指offer40 数组中只出现一次的数字)
136. Single Number 除了一个数字,其他数字都出现了两遍. 用亦或解决,亦或的特点:1.相同的数结果为0,不同的数结果为1 2.与自己亦或为0,与0亦或为原来的数 class Solu ...
- 【刷题-LeeetCode】260. Single Number III
Single Number III Given an array of numbers nums, in which exactly two elements appear only once and ...
随机推荐
- Tomcat 的 SSL 配置
本教程使用 JDK 6 和 Tomcat 7,其他版本类似. 基本步骤: 使用 java 创建一个 keystore 文件 配置 Tomcat 以使用该 keystore 文件 测试 配置应用以便使用 ...
- jQuery各种选择器总结
首先介绍几个简单的: id选择器 $('#p1').html('<font color='red'>nihao</font>); 类选择器:表示页面上所有应用了a样式的标签 $ ...
- PHP-popen() 函数打开进程文件指针
待更新 版权声明:本文为博主原创文章,未经博主允许不得转载.
- 单点登录SSO原理
最近接触了一点单点登录的知识,有一点理解,记录一下.有些问题并没有找到完美的解决方法,还需要找点已有框架来看看. 欢迎留言探讨. 1 概念 1.1 概念及理解 有一个网上广为流传的 ...
- [DEncrypt] HashEncode--哈希加密帮助类 (转载)
点击下载 HashEncode.zip 这个类是关于加密,解密的操作,文件的一些高级操作1.HashEncode 得到随机哈希加密字符串2.HashEncode 得到一个随机数值3.HashEncod ...
- SQL生成一柱双色球
数据库环境:SQL SERVER 2005 以前用C/JAVA穷举双色球的所有排列,今天想着换成用SQL实现,只生成一柱双色球. 简单说下双色球的规则,双色球由红色球和蓝色球组成,每注投注号码由6个红 ...
- localStorage.ie6.js
!window.localStorage && function() { window.localStorage = {}; var prefix = 'data-userdata' ...
- DateTimePicker时间控件:
DateTimePicker时间控件: http://xdsoft.net/jqplugins/datetimepicker/ 可以参考文档设置各种属性,格式. 用法: 首先下载datetimepic ...
- 关于安卓启动eclipse错误:找不到元素‘d:devices'的声明
可以把C:\Documents and Settings\Administrator\.android\devices.xml这个文件删除, 再把sdk里面tools\lib下的这个文件拷贝到你删除的 ...
- chromium安装flash
sudo apt-get install pepperflashplugin-nonfree sudo update-pepperflashplugin-nonfree --install Flash ...