single number

题目描述:

一个数组中除了一个数出现p次外,其他每个数出现k次,p % k != 0,找出这个数。

算法分析:

bit manipulation

https://leetcode.com/problems/single-number-ii/discuss/43295/Detailed-explanation-and-generalization-of-the-bitwise-operation-method-for-single-numbers

  1. 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 };
  2. 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就为那个只出现一次的数字,证明在上述链接中。

  3. 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 }; 

     

原文地址:https://www.cnblogs.com/betaa/p/10653809.html