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?
[分析]
参考
https://leetcode.com/discuss/52351/accepted-java-space-easy-solution-with-detail-explanations,粘贴下作者解析:
引用
Once again, we need to use XOR to solve this problem. But this time, we need to do it in two passes:
In the first pass, we XOR all elements in the array, and get the XOR of the two numbers we need to find. Note that since the two numbers are distinct, so there must be a set bit in the XOR result. Find out the bit.
In the second pass, we divide all numbers into two groups, one with the aforementioned bit set, another with the aforementinoed bit unset. Two different numbers we need to find must fall into thte two distrinct groups. XOR numbers in each group, we can find a number in either group.
Complexity:
Time: O (n)
Space: O (1)
http://www.cnblogs.com/daijinqiao/p/3352893.html 这篇博客中作者给出更一般化的扩展:
引用
给定一个包含n个整数的数组,有一个整数x出现b次,一个整数y出现c次,其他所有的数均出现a次,其中b和c均不是a的倍数,找出x和y。
思路:使用二进制模拟a进制,累计二进制位1出现的次数,当次数达到a时,对其清零,这样可以得到b mod a次x,c mod a次y的累加。遍历剩余结果(用ones、twos、fours...变量表示)中每一位二进制位1出现的次数,如果次数为b mod a 或者 c mod a,可以说明x和y的当前二进制位不同(一个为0,另一个为1),据此二进制位将原数组分成两组,一组该二进制位为1,另一组该二进制位为0。这样问题变成“除了一个整数出现a1次(a1 = b 或 a1 = c)外所有的整数均出现a次”,使用和上面相同的方式计算就可以得到最终结果,假设模拟a进制计算过程中使用的变量为ones、twos、fours...那么最终结果可以用ones | twos | fours ...表示。
我实现了一个具体的例子,一个数组中有一个数出现了1次,一个数出现了两次,其余数均出现了3次。代码有些长,希望面试中不用写这么繁琐的扩展~O(∩_∩)O
public class Solution {
public int[] singleNumber(int[] nums) {
int xor = 0;
for (int num : nums) //记仅出现一次的两数为a和b, for 循环结束,xor=a^b
xor ^= num;
xor &= -xor; // set a 和 b 第一个不同的数位为1,其余位为0
int[] ret = {0, 0};
for (int num : nums) {
if ((num & xor) == 0)
ret[0] ^= num;
else
ret[1] ^= num;
}
return ret;
}
}
import java.util.ArrayList;
public class OutlierNumbers {
public static void main(String[] args) {
OutlierNumbers obj = new OutlierNumbers();
int[] nums = {1,2,2,3,3,3,4,4,4,5,5,5};
int[] ret = obj.getOutliers(nums);
}
// 一个数出现a次,一个数出现b次,其余数均出现c次的一个具体化例子: a = 1, b = 2, c = 3
public int[] getOutliers(int[] nums) {
int ones = 0, twos = 0;
int mask = 0;
for (int num : nums) {
twos |= (ones & num);
ones ^= num;
mask = ~(ones & twos);
ones &= mask;
twos &= mask;
}
int xor = ones ^ twos;
xor &= -xor;
int[] ret = new int[2];
ArrayList<Integer> group1 = new ArrayList<Integer>();
ArrayList<Integer> group2 = new ArrayList<Integer>();
for (int num : nums) {
if ((xor & num) == 0)
group1.add(num);
else
group2.add(num);
}
int[] array1 = arrayList2Array(group1);
int[] array2 = arrayList2Array(group2);
if (array1.length % 3 == 1)
ret[0] = getOneOutlier(array1, true);
else
ret[0] = getOneOutlier(array1, false);
if (array2.length % 3 == 1)
ret[1] = getOneOutlier(array2, true);
else
ret[1] = getOneOutlier(array2, false);
System.out.println(ret[0] + " " + ret[1]);
return ret;
}
public int getOneOutlier(int[] nums, boolean outlierOccurOne) {
if (nums == null) return Integer.MAX_VALUE;
if (nums.length < 3) return nums[0];
int ones = 0, twos = 0;
int mask = 0;
for (int num : nums) {
twos |= (ones & num);
ones ^= num;
mask = ~(ones & twos);
ones &= mask;
twos &= mask;
}
if (outlierOccurOne)
return ones;
else
return twos;
}
public int[] arrayList2Array(ArrayList<Integer> list) {
int[] array = new int[list.size()];
for (int i = 0; i < list.size(); i++)
array[i] = list.get(i);
return array;
}
}
分享到:
相关推荐
javascript js_leetcode题解之136-single-number.js
- **2.1.24 Single Number II** - 找出数组中只出现一次的数字,其余数字均出现三次。 - 实现思路:位操作,利用位掩码记录每位出现次数。 - **2.2 单链表** - **2.2.1 Add Two Numbers** - 两个链表表示的...
python python_leetcode题解之136_Single_Number
python python_leetcode题解之137_Single_Number_II
- **单一数字问题(Single Number)**: 找出数组中唯一的不重复的数字。 - **快乐数(Happy Number)**: 判断一个数字是否快乐。 - **二进制中的1的个数(Count 1 in Binary)**: 计算一个整数的二进制表示中有多少个1。 ...
leetcode 答案leetcode-java leetcode.com 的 Java 答案 ================索引================ ...Single Number com.leetcode.tree Balanced Binary Tree Maximum Depth of Binary Tree Same Tree
《位运算处理数组中的数——以LeetCode Single Number II为例》 在计算机科学中,位运算是一种高效且灵活的数据处理手段,尤其在处理数组中特定数值的问题时,它能展现出强大的能力。LeetCode上的Single Number II...
dna匹配 leetcode leetcode刷题--C++ ...Single Number 异或 Copy List with Random Pointer 单链表 map Max Points on a Line 斜率 map, int> Fraction to Recurring Decimal map long long 正负号 Repeated DNA S
Leetcode的ac是什么意思 LeetCodeInJava List #98 Validate Binary Search Tree #100 Same Tree #104 Maximum Depth of Binary Tree #122 Best Time to Buy and Sell Stock II #136 Single Number #150 Evaluate ...
颜色分类leetcode leetcode.etc My solutions of the problems in Online judge website, leetcode, lintcode, etc. leetcode: 13 problems solved lintcode: 49 problems solved Title URL Solution Difficulty ...
这些文件名可能类似于"Day01_SingleNumber.cpp"、"Day02_ValidPalindrome.cpp"等,按照日期和题目内容命名,方便查阅和学习。通过查看和分析这些源代码,我们可以深入了解每道题目的解题思路,学习不同算法的应用,...
7. **位运算**:用于高效地处理整数,例如在`SingleNumber.java`中找出只出现一次的数字。 8. **设计模式**:如工厂模式、单例模式、观察者模式等。虽然LeetCode主要关注算法,但某些问题可能需要设计合理的类结构...
single-number 动态规划 candy 贪心 gas-station 动态规划 palindrome-partitioning-ii 动态规划 triangle 树 sum-root-to-leaf-numbers 动态规划 distinct-subsequences 递归 valid-palindrome 模拟 pascals-...
https://leetcode.com/problems/single-number/ level : - easy tags : - recursive - linked list solutions : - reverseList - runtime : 52 ms, beats 99.80% - memory : 35 MB, beats 47.37% - ...
3. **Single Number** (数组中只出现一次的数字): 题目要求找出数组中唯一出现一次的数字,其余数字都出现了两次。这涉及到位运算,可以利用异或操作符在Java中解决这个问题,因为任何数与其自身异或的结果是0,所有...
leetcode 浇花力扣解决方案 简单的 #0001 - Two Sum #0007 - Reverse Integer #0009 - Palindrome Number #0035 - Search Insert Position #0058 - Length of Last Word #0066 - Plus One #0083 - Remove Duplicates...
260 | [Single Number III](https://leetcode.com/problems/single-number-iii/) | [C++](./C++/single-number-iii.cpp) [Python](./Python/single-number-iii.py) | _O(n)_ | _O(1)_ | Medium || 268| [Missing ...
SingleNumber 其他算法 各种SingleNumber变种 LinkListCycle I II 其他变种 编程之美 Preorder Traversal Inorder Traver sal postorder 非递归 不用栈! 字符串常用操作 字符串 各种转换 Pow(x,n) 优化 ...
只出现一次的数字 III(Single Number III)**:这是一道关于数组和位操作的题目,要求找出数组中唯一一个只出现一次的数字,而其他数字都出现两次。可以利用异或操作实现。 7. **338. 计数质数(Counting Bits)**:...
Single Number 碰巧我知道异或的解法。如果不知道的话,想想还是有点费事的。 Maximum Depth of Binary Tree 这?也太简单了吧。。一行代码,一个尾递归搞定啊。。 终于想清楚了,leetcode的AC率应该是:在线编辑、...