leetcode oj java 260. Single Number III
2017-01-04 11:34
295 查看
一、问题描述:
Given an array of numbers
the other elements appear exactly twice. Find the two elements that appear only once.
For example:
Given
Note:
The order of the result is not important. So in the above example,
also correct.
Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
二、解决思路:
我们知道如果数组中是只有一个出现一次,其余都出现两次的话,可以直接用异或的方式得到这个数字(一个数字异或自己得到0,那么出现次数为2的数字异或完之后就是0,单独出现一次
的数字异或0变成它自己)。
现在数组中有两个数字只出现一次。如果我们把这个数组分成两个数组,每个数组中包含一个只出现一次的数字以及其余数字都出现两次,分别对每个数组进行上述的操作就可以得到只出现
一次的数字。
那么如果划分数组才可以保证每个数组中包含一个只出现一次的数字以及其余数字都出现两次?
遍历整个数组,求得异或的值。 这个值相当于两个只出现一次的数字的异或,必然不为0. 我们找到第一个为1的位置n。遍历整个数组。如果元素的第n位是1,那就放到数组l1中,否则放到数
组l2中。 此时l1中是两个只出现一次的数字中第n位是1的数字以及剩下的出现两次的数值中第n位为1的数字。l2中是剩下的数字。即根据第n位是否为1把那些出现两次的数字分为2组。(相同的数字
不可能分别出现在两个数组中了)
三、代码:
public class Solution {
public int[] singleNumber(int[] nums) {
int[] re = new int[2];
int tmp = nums[0];
for (int i = 1; i < nums.length; i++) {
tmp = tmp ^ nums[i];
}
// find first one
int n = 0;
while ((tmp & 1) == 0) {
tmp = tmp >> 1;
n++;
}
// split
List<Integer> l1 = new ArrayList<Integer>();
List<Integer> l2 = new ArrayList<Integer>();
for (int i = 0; i < nums.length; i++) {
int t = nums[i];
int bit = n;
while (bit > 0) {
t = t >> 1;
bit--;
}
if ((t & 1) == 0) {
l1.add(nums[i]);
} else {
l2.add(nums[i]);
}
}
re[0] = l1.get(0);
for (int i = 1; i < l1.size(); i++) {
re[0] = re[0] ^ l1.get(i);
}
re[1] = l2.get(0);
for (int i = 1; i < l2.size(); i++) {
re[1] = re[1] ^ l2.get(i);
}
return re;
}
}
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?
二、解决思路:
我们知道如果数组中是只有一个出现一次,其余都出现两次的话,可以直接用异或的方式得到这个数字(一个数字异或自己得到0,那么出现次数为2的数字异或完之后就是0,单独出现一次
的数字异或0变成它自己)。
现在数组中有两个数字只出现一次。如果我们把这个数组分成两个数组,每个数组中包含一个只出现一次的数字以及其余数字都出现两次,分别对每个数组进行上述的操作就可以得到只出现
一次的数字。
那么如果划分数组才可以保证每个数组中包含一个只出现一次的数字以及其余数字都出现两次?
遍历整个数组,求得异或的值。 这个值相当于两个只出现一次的数字的异或,必然不为0. 我们找到第一个为1的位置n。遍历整个数组。如果元素的第n位是1,那就放到数组l1中,否则放到数
组l2中。 此时l1中是两个只出现一次的数字中第n位是1的数字以及剩下的出现两次的数值中第n位为1的数字。l2中是剩下的数字。即根据第n位是否为1把那些出现两次的数字分为2组。(相同的数字
不可能分别出现在两个数组中了)
三、代码:
public class Solution {
public int[] singleNumber(int[] nums) {
int[] re = new int[2];
int tmp = nums[0];
for (int i = 1; i < nums.length; i++) {
tmp = tmp ^ nums[i];
}
// find first one
int n = 0;
while ((tmp & 1) == 0) {
tmp = tmp >> 1;
n++;
}
// split
List<Integer> l1 = new ArrayList<Integer>();
List<Integer> l2 = new ArrayList<Integer>();
for (int i = 0; i < nums.length; i++) {
int t = nums[i];
int bit = n;
while (bit > 0) {
t = t >> 1;
bit--;
}
if ((t & 1) == 0) {
l1.add(nums[i]);
} else {
l2.add(nums[i]);
}
}
re[0] = l1.get(0);
for (int i = 1; i < l1.size(); i++) {
re[0] = re[0] ^ l1.get(i);
}
re[1] = l2.get(0);
for (int i = 1; i < l2.size(); i++) {
re[1] = re[1] ^ l2.get(i);
}
return re;
}
}
相关文章推荐
- leetcode-java-260. Single Number III
- LeetCode oj 260. Single Number III (位运算)
- Single Number III leetcode java
- 260.Single Number III
- 260. Single Number III
- [leetcode] 260.Single Number III
- leetcode-260. Single Number III
- [leetcode] 260. Single Number III 解题报告
- LeetCode 260. Single Number III
- LeetCode *** 260. Single Number III
- LeetCode 260 -Single Number III ( JAVA )
- 【LeetCode】260. Single Number III
- [LeetCode]260. Single Number III
- 260. Single Number III
- LeetCode Single Number III (Java和Python代码)
- 【LeetCode OJ 260】Single Number III
- Leet Code OJ 260. Single Number III [Difficulty: Medium]
- 260. Single Number III
- 260. Single Number III -取出非重复数字(加强版)
- 260. Single Number III