问题描述136:
Given a non-empty array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
Example 1:
Input: [2,2,1]
Output: 1
Example 2:
Input: [4,1,2,1,2]
Output: 4
源码136:
最近leetcode貌似又出问题了,所以的方法效率都贼低,都是不到10%那样。等后面修复好了我在展示吧。
这题是剑指offer第56题剑指offer总纲的一个简易版。所有数字异或本身都是0,0与数字异或等于本身,所以我们吧所有的元素异或到一起,就解决了问题。Solution里面也太扯了,不是时间不是线性就用了额外空间,根本不满足题目要求。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int n = nums.size(), result=nums[0];
for(int i=1; i<n; i++){
result ^= nums[i];
}
return result;
}
};
问题描述137:
Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
Example 1:
Input: [2,2,3,2] Output: 3
Example 2:
Input: [0,1,0,1,0,1,99] Output: 99
源码137:
同样是剑指offer的第56问剑指offer总纲。因为用到的数组都是常熟大小的,内循环也是常数的,所以时间是线性的,空间是常数的。
思路就是统计int类型每一位的数字,然后%3,这样就能筛出需要的数字。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int n=nums.size();
int bitsum[32] = {0};
for(int i=0; i<n; i++){
long bitmask = 1;
for(int j=31; j>=0; j--){
int bit = nums[i] & bitmask;
if(bit) bitsum[j] += 1;
// cout<<bitmask<<endl;
bitmask = bitmask<<1;
}
}
int result = 0;
for(int i=0; i<32; i++){
result = result<<1;
result += bitsum[i] % 3;
}
return result;
}
};
大佬的博客上有比较简洁的做法,思路还是一样的:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int n = nums.size(), result = 0;
for(int i=0; i<32; i++){
int sum = 0;
for(int j=0; j<n; j++){
sum += (nums[j]>>i) & 1;
}
result += (sum % 3)<<i;
}
return result;
}
};