Single Number - Complete Solution Guide
Single Number is LeetCode problem 136, a Easy level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
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. 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.
Detailed Explanation
The 'Single Number' problem presents a deceptively simple challenge: given an array of integers where every number appears exactly twice, save for one unique outlier, your task is to pinpoint that lone number. For instance, in `[2,2,1]`, '1' is the one. In a more complex example like `[4,1,2,1,2]`, '4' is the elusive individual. The problem statement guarantees the array is non-empty and there's always exactly one number that doesn't have a pair. All numbers fit within a standard integer range. What elevates this problem beyond a straightforward counting exercise are the tight constraints. We're strictly mandated to achieve a solution with linear time complexity – meaning we can't afford to re-process the array multiple times or use algorithms with quadratic growth. Even more critically, we must accomplish this using only constant extra space. This immediately rules out common, intuitive approaches like building a frequency map (hash map/dictionary) to count occurrences, as that would consume space proportional to the number of unique elements, not a constant amount. The true puzzle lies in finding a mathematical or bitwise trick that can 'filter out' the pairs without storing them, leaving only the single number behind. It forces us to think beyond conventional data structures and leverage intrinsic properties of numbers themselves to meet the strict space requirement while still being efficient.
Solution Approach
The elegance of the provided solution hinges entirely on the properties of the bitwise XOR operator (`^`). The core idea is that XORing a number with itself always yields zero (`A ^ A = 0`), and XORing any number with zero returns the number itself (`A ^ 0 = A`). Furthermore, XOR is both commutative and associative, meaning the order in which we perform XOR operations doesn't change the final result (e.g., `A ^ B ^ C` is the same as `C ^ A ^ B`). With these properties in mind, consider what happens when we XOR every number in the input array `nums` together, starting with an initial `result` of 0. When we encounter a number that appears twice, say `X`, it will contribute `X ^ X` to the cumulative XOR sum at some point. Since `X ^ X` evaluates to `0`, these pairs effectively cancel each other out, disappearing from the running total. Because of associativity, it doesn't matter if the two `X`'s are adjacent or separated by other numbers; their combined effect on the `result` will always be `0`. Consequently, after iterating through the entire array, all the numbers that appear twice will have 'XORed themselves out' to zero. The only number left standing in our `result` variable will be the unique element, XORed with zero (from the cancelled pairs and the initial `result`), which, by the `A ^ 0 = A` property, will simply be the unique number itself. This one-pass approach gives us linear time complexity, and since we only use a single `result` variable, it perfectly satisfies the constant extra space constraint.
Step-by-Step Algorithm
- Step 1: Initialize a variable `result` to 0. This will accumulate the XOR results.
- Step 2: Iterate through the input array `nums`.
- Step 3: For each number `num` in `nums`, perform a bitwise XOR operation: `result ^= num`.
- Step 4: After iterating through all numbers, the `result` variable will hold the unique number.
Key Insights
- **The 'self-cancelling' nature of XOR:** The most crucial insight is `X ^ X = 0`. This allows duplicate numbers to effectively 'erase' each other from the cumulative XOR sum, regardless of their position in the array. It's like they form a pair and disappear.
- **XOR's identity property for result preservation:** The property `X ^ 0 = X` ensures that the unique number, once all pairs have cancelled out, remains as the final accumulated result. Starting our `result` variable at `0` correctly leverages this identity element for XOR accumulation.
- **Bitwise operations for superior space efficiency:** Utilizing XOR bypasses the need for auxiliary data structures (like hash maps or frequency arrays) that would typically store counts. This characteristic of XOR perfectly meets the strict constant space complexity requirement without sacrificing linear time performance, making it an extremely elegant solution for this problem type.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(1)
Topics
This problem involves: Array, Bit Manipulation.
Companies
Asked at: Airbnb, Cisco, Google, Nvidia, Palantir Technologies, Qualcomm, Yahoo, Yandex, Zoho, tcs.