Alkesh

LeetCode - Single Number

Problem statement

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.

Problem statement taken from: https://leetcode.com/problems/single-number.

Example 1:

Input: nums = [2, 2, 1]
Output: 1

Example 2:

Input: nums = [4, 1, 2, 1, 2]
Output: 4

Example 3:

Input: nums = [1]
Output: 1

Constraints:

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

Explanation

Brute force solution

The brute force solution is to check if every element appears once or not. Once an element with a single occurrence is found, we return that element. The time complexity of the above approach is O(N^2).

The time complexity can be reduced to O(N) by using hashing. We traverse all the elements in an array and put them in the hash table. Array element will be the key in the hash table, and its value will be the count of occurrences of that element in the array.

A C++ snippet for this approach is as below:

int singleNumber(vector<int>& nums) {
    map<int, int> m;

    for(int i = 0; i < nums.size(); i++) {
        m[nums[i]]++;
    }

    for(auto const & [key, value]: m) {
        if(value == 1) {
            return key;
        }
    }

    return -1;
}

The time complexity is reduced to O(N), but space complexity has increased to O(N).

Optimized solution

We can reduce the space complexity to O(1), by using a single int variable. We can use the arithmetic XOR operator ^. An XOR operator returns 0 when the operands are similar.

3 ^ 1
=> 2

3 ^ 2
=> 0

3 ^ 0
=> 3

Since every element in an array appears twice except one, the XOR for all duplicates will return 0. And XOR for any non-zero number with zero will return the same number. We need to iterate over the array and perform XOR for all the elements.

Let's check the algorithm now.

- initialize singleNum = 0

- loop for i = 0; i < nums.size(); i++
  - singleNum ^= nums[i]

- return singleNum

Let's check out our solutions in C++, Golang, and Javascript.

C++ solution

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int singleNum = 0;

        for(int i = 0; i < nums.size(); i++) {
            singleNum ^= nums[i];
        }

        return singleNum;
    }
};

Golang solution

func singleNumber(nums []int) int {
    singleNum := 0

    for i := 0; i < len(nums); i++ {
        singleNum ^= nums[i]
    }

    return singleNum
}

Javascript solution

var singleNumber = function(nums) {
    let singleNum = 0;

    for(let i = 0; i < nums.length; i++) {
        singleNum ^= nums[i];
    }

    return singleNum;
};

Dry Run

Let's dry-run our algorithm to see how the solution works.

Input: nums = [4, 1, 2, 1, 2]

Step 1: singleNum = 0

Step 2: loop for i = 0; i < nums.size()
          0 < 5
          true

          singleNum ^= nums[i]
                     = singleNum ^ nums[0]
                     = 0 ^ 4
                     = 4

          i++
          i = 1

Step 3: i < nums.size()
          1 < 5
          true

          singleNum ^= nums[i]
                     = singleNum ^ nums[1]
                     = 4 ^ 1
                     = 5

          i++
          i = 2

Step 4: i < nums.size()
          2 < 5
          true

          singleNum ^= nums[i]
                     = singleNum ^ nums[2]
                     = 5 ^ 2
                     = 7

          i++
          i = 3

Step 5: i < nums.size()
          3 < 5
          true

          singleNum ^= nums[i]
                     = singleNum ^ nums[3]
                     = 7 ^ 1
                     = 6

          i++
          i = 4

Step 6: i < nums.size()
          4 < 5
          true

          singleNum ^= nums[i]
                     = singleNum ^ nums[4]
                     = 6 ^ 2
                     = 4

          i++
          i = 5

Step 7: i < nums.size()
          5 < 5
          false

Step 8: return singleNum

So we return the answer as 4.
Share this post!