260. 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]
.
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?
链接: http://leetcode.com/problems/single-number-iii/
题解:
昨晚卡到现在。但昨晚睡觉前google了一下,看到了几篇文章以后才理解。还是需要加强bit manipulation。 归根结底是大学时数字电路没学好 -_____-!! 我不堪的本科生涯...略去一亿字。
这里我们主要是先异或所有数字,得到 a^b, 因为a和b不相等,所以 a^b里至少有一个bit位k,k = 1。 然后我们就可以用这个第k位来进行判断, 因为a和b里只有一个数第k位 = 1,我们对输入数组所有第k位为1的数字进行异或,就可以找到第k位为1的仅出现一次的数字, 再用这个数字a和 a^b进行异或,我们也就求得了b。
Time Complexity - O(n), Space Complexity - O(1)。
public class Solution { public int[] singleNumber(int[] nums) { int[] res = {-1, -1}; if(nums == null || nums.length == 0) { return res; } int a_XOR_b = 0; for(int i = 0; i < nums.length; i++) { // find a ^ b a_XOR_b ^= nums[i]; } int k = 0; // find one bit in a^b == 1 for(int i = 0; i < 31; i++) { // that means only one num in a, b has 1 on kth bit if(((a_XOR_b >> i) & 1) == 1) { k = i; break; } } int a = 0; for(int i = 0; i < nums.length; i++) { // since only one num in a, b has 1 on kth bit if(((nums[i] >> k) & 1) == 1) { // we can XOR all nums has 1 on kth bit a ^= nums[i]; // duplicate nums will be evened out } } int b = a ^ a_XOR_b; res[0] = a; res[1] = b; return res; } }
二刷:
也是用一刷一样的方法,比较tricky
Java:
public class Solution { public int[] singleNumber(int[] nums) { int[] res = {-1, -1}; if (nums == null || nums.length == 0) { return res; } int a_XOR_b = 0; for (int i : nums) { a_XOR_b ^= i; } int k = 0; for (int i = 0; i < 32; i++) { if (((a_XOR_b >> i) & 1) == 1) { k = i; break; } } res[0] = 0; for (int i : nums) { if (((i >> k) & 1) == 1) { res[0] ^= i; } } res[1] = a_XOR_b ^ res[0]; return res; } }
题外话:
其实本科时,学校开设的课程挺不错的,老师也努力务实,都怪自己没把心思放在学习上。虽然专业是EE,但像什么基数排序,霍夫曼编码,游程码,最短路径之类的东西,老师们也都多少介绍过。信息量很大,作业和考试也难。真要四年扎扎实实学下来的话,也不至于现在一把年纪了还在刷题。 过去的都过去了,接下来好好努力吧。
三刷:
这次就比较熟练了,尝试一些不同的编程风格。 4/4/2016。
Java:
Time Complexity - O(n), Space Complexity - O(1)。
public class Solution { public int[] singleNumber(int[] nums) { int[] res = new int[2]; if (nums == null || nums.length < 2) return res; int a_xor_b = 0; for (int num : nums) { a_xor_b ^= num; } int diffIndex = 0; while (diffIndex < 32) { if (((a_xor_b >> diffIndex) & 1) == 1) { break; } diffIndex++; } int num1 = 0; for (int num : nums) { if (((num >> diffIndex) & 1) == 1) { num1 ^= num; } } res[0] = num1; res[1] = a_xor_b ^ num1; return res; } }
Update:
public class Solution { public int[] singleNumber(int[] nums) { if (nums == null || nums.length < 2) return new int[] {-1, -1}; int a_XOR_b = 0; for (int num : nums) a_XOR_b ^= num; int k = 0; while (k < 31) { if (((a_XOR_b >> k) & 1) == 1) break; k++; } int a = 0; for (int num : nums) { if (((num >> k) & 1) == 1) a ^= num; } return new int[] {a, a ^ a_XOR_b}; } }
Reference:
https://groups.google.com/forum/#!topic/pongba/9KCA7b484OE
https://groups.google.com/forum/#!topic/pongba/drV6dytcoJE
http://www.matrix67.com/blog/archives/511