Leetcode No.136 single number (c + + implementation)

Time:2021-12-22

1. Title

1.1 English title

Given a non-empty array of integers nums, every element appears twice except for one. Find that single one.

You must implement a solution with a linear runtime complexity and use only constant extra space.

1.2 Chinese title

Given a non empty array of integers, each element appears twice except that one element appears only once. Find the element that appears only once.

explain:
Your algorithm should have linear time complexity. Can you do it without using extra space?

1.3 input and output

input output
nums = [2,2,1] 4
nums = [4,1,2,1,2] 4
nums = [1] 1

1.4 constraints

  • 1 <= nums.length <= 3 * 104
  • -3 * 104 <= nums[i] <= 3 * 104
  • Each element in the array appears twice except for one element which appears only once.

2. Analysis

My first reaction to this question is violent search. First, build a temporary array to store the traversed elements. If the new traversal element repeats with the previous one, it is not the target value and is deleted from the temporary array; Otherwise join. After traversing to the end, only the target value remains in the temporary array. The code is as follows:

class Solution {
public:
    int singleNumber(vector& nums) {
        vector temp;
        vector::iterator iter;
        for (int i = 0; i < nums.size(); i++)
        {
            iter = find(temp.begin(), temp.end(), nums[i]);
            If (ITER! = temp. End()) // found, duplicate element
                temp.erase(iter);
            else
                temp.push_back(nums[i]);
        }
        return temp[0];
    }
};

Then I looked at the writing of some other great gods, which made people call it wonderful! One is to use the property that the set does not contain duplicate elements, convert the array into a set, and then subtract the sum of all elements of the original array by twice the sum of the elements of the set. The code is as follows:

class Solution {
public:
    int singleNumber(vector& nums) {
        set setNums(nums.begin(), nums.end());
        int sum = accumulate(nums.begin(), nums.end(), 0);
        int setSum = accumulate(setNums.begin(), setNums.end(), 0);
        return 2 * setSum - sum;
    }
};

The above algorithm is not very good in time and space consumption, but this idea is good. Another way is to use the XOR property, assuming that all arrays are: ABC bcda, then
a ^ b ^ c ^ b ^ c ^ d ^ a
= a ^ a ^ b ^ b ^ c ^ c ^ d
= 0 ^ 0 ^ 0 ^ d
= d。
The code is as follows:

class Solution {
public:
    int singleNumber(vector& nums) {
        int result = 0;
        for (auto num : nums)
            result ^= num;
        return result;
    }
};

3. Supplementary knowledge

(1)vector

a. Find an element in the vector

You can use find() in the algorithm header file. The usage is:
vector::iterator iter = std::find(vec.begin(), vec.end(), findNum);

b. Vector prune element

  • push_ Add element at the end of back()
  • pop_ Delete element at the end of back()
  • Erase (Num) deletes the specified element or the specified iterator location element

c. Vector and set turn to each other

  • Vector to set:set st(v.begin(), v.end());// Vector to set can be directly implemented in the constructor
  • Set to vector:v.assign(st.begin(), st.end());

(2) XOR

a. Characteristics of XOR:

  • Constant law: A ^ 0 = a
  • Zeroing rate: A ^ a = 0
  • Commutative law: A ^ B = B ^ A
  • Binding law: (a ^ b) ^ C = a ^ (b ^ C)

b. Use

XOR can quickly compare whether two values are equal. A ^ B = = 0 is very efficient, which is much higher than a – B = = 0.

XOR can also exchange two values without defining temporary variables (classic topic)
a = a ^ b
b = a ^ b // a ^ b ^ b = a ^ 0 = a
a = a ^ b // a ^ b ^ a = b ^ 0 = b
reference resources:https://www.jianshu.com/p/e3442ed3d874