single number
题目描述:
一个数组中除了一个数出现p次外,其他每个数出现k次,p % k != 0,找出这个数。
算法分析:
bit manipulation
- Given a non-empty array of integers, every element appears twice except for one. Find that single one.
time complexity: O(n)
space complexity: O(1)
https://leetcode.com/problems/single-number/
1 class Solution { 2 public: 3 int singleNumber(vector<int>& nums) { 4 for(int i = 1; i < nums.size(); i++) 5 nums[0] ^= nums[i]; 6 return nums[0]; 7 } 8 };
- Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
time complexity: O(n)
space complexity: O(1)
https://leetcode.com/problems/single-number-ii/
1 class Solution { 2 public: 3 int singleNumber(vector<int>& nums) { 4 int x1 = 0, x2 = 0, mask = 0; 5 for(int i : nums){ 6 x2 ^= x1 & i; 7 x1 ^= i; 8 mask = ~(x1 & x2); 9 x2 &= mask; 10 x1 &= mask; 11 } 12 return x1; 13 } 14 };
每一步循环时输出相应x1,x2,和mask的值:1 #include <iostream> 2 #include <string> 3 #include <sstream> 4 #include <algorithm> 5 #include <vector> 6 #include <bitset> 7 using namespace std; 8 9 int single(vector<int> nums){ 10 int x1 = 0, x2 = 0, mask = 0; 11 for(int i : nums){ 12 x2 ^= x1 & i; 13 x1 ^= i; 14 mask = ~(x1 & x2); 15 x2 &= mask; 16 x1 &= mask; 17 cout << i << ":" << endl; 18 cout << "mask :" << bitset<4>(mask) << endl; 19 cout << "x2: " << bitset<4>(x2) << endl; 20 cout << "x1: " << bitset<4>(x1) << endl; 21 cout << endl; 22 } 23 return x1; 24 } 25 26 int main(){ 27 vector<int> nums = {2, 2, 3, 2}; 28 int res = single(nums); 29 cout << "single number: "<< res << endl; 30 return 0; 31 }
可以发现,x2的i-th bit和x1的i-th bit构成一个counter,来计数数组中数字i-th bit 出现1的次数,每次达到k,就将其置为0,将p表示为二进制数,若i-th bit不为0,则xi就为那个只出现一次的数字,证明在上述链接中。
输出: - 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.
time complexity: O(n)
space complexity: O(1)
https://leetcode.com/problems/single-number-iii/
1 class Solution 2 { 3 public: 4 vector<int> singleNumber(vector<int>& nums) 5 { 6 // Pass 1 : 7 // Get the XOR of the two numbers we need to find 8 int diff = accumulate(nums.begin(), nums.end(), 0, bit_xor<int>()); 9 // Get its last set bit 10 diff &= -diff; 11 12 // Pass 2 : 13 vector<int> rets = {0, 0}; // this vector stores the two numbers we will return 14 for (int num : nums) 15 { 16 if ((num & diff) == 0) // the bit is not set 17 { 18 rets[0] ^= num; 19 } 20 else // the bit is set 21 { 22 rets[1] ^= num; 23 } 24 } 25 return rets; 26 } 27 };