Single Number系列
Single Number I
Given an array of integers, every element appears twice except
for one. Find that single one.
题目描述:
给出一个数组arr,数组中每个元素都仅出现两次,除了其中一个数只出现一次,找出那个数。
思想:
主要的思想是用异或来做,两个相同的数异或后会变为0,所以对数组进行异或,最后得到的结果就是只出现一次的数。
代码:
JAVA AC 时间O(n) 空间O(1)
class Solution {
public int singleNumber(int[] nums) {
int len = nums.length;
if(len<=0) return -1;
int res = nums[0];
for(int i=1;i<len;i++){
res^=nums[i];
}
return res;
}
}
Single Number II
Given an array of integers, every element appears three times
except for one, which appears exactly once. Find that single one.
题目描述:
思想:
考虑全部用二进制表示,如果我们把第i个位置上所有数字的和对3取余,那么只会有两个结果 0 或 1 (根据题意,3个0或3个1相加余数都为0). 因此取余的结果就是那个 “Single Number”。一个直接的实现就是用大小为 32的数组来记录所有位上的和。
代码:
C++ AC 时间O(n) 空间O(1)
class Solution {
public:
int singleNumber(vector<int>& nums) {
int len = nums.size();
int res = 0;
for(int j=0;j<32;j++){
int sum = 0; //二进制所有数每一位的数字之和
for(int i=0;i<len;i++){
sum+=((nums[i]>>j)&1);
}
if(sum%3==1){
res |=1<<j;
}
}
return res;
}
};
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]
.
题目描述:
该题目是数组中除了其中2个数只出现一次,其他数都出现了2次,找出这2个数。
思想:
该题目类似于第一题,如果该数组只有一个数出现一次那么可以直接用题目I的逻辑来做
所以我们要对该数组进行分组,把这两个只出现一次的数分别分为A,B两组
那么如何分组呢,首先这两个数肯定是不相同的,那么我们可以把这两个数转化为2进制,进行比较。每一位进行^运算,肯定有其中一位进行^运算后结果为1.
也就是说这两个数在2进制中的这一位,一个是0,一个是1.然后找到这一位的位置,再遍历数组nums,对每个元素的这一位进行^运算,这样通过运算后为0的并入组A,为1的并入组B。
再分别对组A 和 组B进行如题目1的逻辑分别找到对应只出现一次的数。
代码:
C++ AC 时间O(1) 空间O(n)
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
vector<int> res;
if(nums.size()<=0) return res;
int res1=0;
int res2=0;
int index = findFistSum(nums);
for(int i=0;i<nums.size();i++){
if((nums[i]>>index)&1) {res1^=nums[i];}
else {res2^=nums[i];}
}
res.push_back(res1);
res.push_back(res2);
return res;
}
///返回 二个只有1唯一数异或后 他们的二进制的第一位为1的位置
int findFistSum(vector<int>& nums){
//所有数异或
int res = nums[0];
for(int i=1;i<nums.size();i++){
res ^=nums[i];
}
for(int i=0;i<32;i++){
if((res>>i)&1){
return i;
}
}
}
};