来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof
1. 题目
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
- 示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1] - 示例 2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
class Solution {
public int[] singleNumbers(int[] nums) {
}
}
2. JAVA解答
问题的难度不在于如何解决该题目,而是在于如何用时间复杂度O(N),空间复杂度O(1)去解决,这里涉及到一个知识点:同数异或为0,不同数异或不为0;把整个数组进行异或,则实际上就是a ^ b的结果(a,b为题目中正解)。a和b为不同数,则在某一位必然不同,找到该位作为分组依据,分组异或,即可分别得到两个数,总结:妙蛙种子吃着妙脆角妙进了米奇妙妙屋,妙到家了。
![](https://img.haomeiwen.com/i11695305/dc18cb9343c39b3a.png)
class Solution {
public int[] singleNumbers(int[] nums) {
int[] res = new int[2];
int xor = 0;
/***
* [主程序-异或]:相同两数异或得0
* 从最低位开始,如果xor的对应位数为1的话
* 说明res[0]或者res[1]其中一方为1,可以作为分组条件,如果不满足则进行判断倒二位
*/
for(int i:nums){
xor = xor ^ i;
}
int div = 1;
/***
* [主程序-判断]:获得分组标识
* 从最低位开始,如果xor的对应位数为1的话
* 说明res[0]或者res[1]其中一方为1,可以作为分组条件,如果不满足则进行判断倒二位
*/
while((div & xor)==0){
div<<=1;
}
for(int i:nums){
if((div & i) == 0){
res[0] = res[0] ^ i;
}else{
res[1] = res[1] ^ i;
}
}
return res;
}
}
网友评论