961. N-Repeated Element in Size 2N Array
Problem Description
You are given an integer array nums
with specific properties:
- The array has a length of
2 * n
(an even number of elements) - The array contains exactly
n + 1
unique elements - Exactly one element appears
n
times, while all other elements appear exactly once
Your task is to find and return the element that appears n
times.
For example, if n = 2
, the array would have 4 elements total, with 3 unique values. One value would appear 2 times, and the other two values would each appear once. You need to identify which value appears 2 times.
The key insight is that since there are 2n
total elements and n + 1
unique elements, with one element appearing n
times, the remaining n
elements must be the other n
unique values appearing once each. This means any element that appears more than once must be the element that appears n
times.
The solution uses a set to track seen elements. As we iterate through the array, if we encounter an element that's already in the set, it must be the repeated element (since all other elements appear only once), so we can immediately return it.
Intuition
Let's think about the mathematical constraints of this problem. We have 2n
total elements and n + 1
unique elements. If one element appears n
times, that accounts for n
positions in the array. The remaining n
positions must be filled by the other n
unique elements.
Since we have exactly n
remaining positions and n
remaining unique elements, each of these other elements can only appear exactly once. This is the critical observation: every element appears either exactly once or exactly n
times.
This means the moment we see any element for the second time while scanning through the array, we can be certain it's the element that appears n
times. Why? Because if an element appears more than once, it cannot be one of the elements that appears exactly once, so it must be the element that appears n
times.
This leads us to a simple approach: keep track of elements we've seen before using a set. As we iterate through the array:
- If we encounter an element we haven't seen before, add it to our set
- If we encounter an element that's already in our set, this must be our answer - return it immediately
We don't need to count occurrences or track frequencies. The first duplicate we find is guaranteed to be the element that appears n
times, making this a very efficient O(n)
time solution with potentially early termination.
Solution Approach
The implementation uses a hash set to efficiently track elements we've encountered while iterating through the array.
Here's the step-by-step implementation:
-
Initialize a set: Create an empty set
s
to store elements we've seen. -
Iterate through the array: For each element
x
innums
:- Check if element exists: First check if
x
is already in the sets
- If found: If
x
is in the set, this means we've seen it before. Since any repeated element must be the one that appearsn
times (as all others appear exactly once), we immediately returnx
- If not found: Add
x
to the set and continue to the next element
- Check if element exists: First check if
class Solution:
def repeatedNTimes(self, nums: List[int]) -> int:
s = set()
for x in nums:
if x in s:
return x
s.add(x)
Time Complexity: O(n)
in the worst case, where we might need to check up to n + 1
elements before finding the duplicate. However, the algorithm often terminates early since the repeated element appears n
times in 2n
positions.
Space Complexity: O(n)
in the worst case for storing up to n
unique elements in the set before finding the duplicate.
The beauty of this solution is its simplicity - we don't need to count frequencies or use complex data structures. The mathematical constraints of the problem guarantee that the first duplicate we encounter is our answer.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example to see how the solution works.
Example Input: nums = [5, 1, 5, 2, 5, 3, 5, 4]
In this case:
- Array length = 8, so
2n = 8
, meaningn = 4
- We have 5 unique elements: {1, 2, 3, 4, 5}
- Element 5 appears 4 times (which is
n
times) - Elements 1, 2, 3, 4 each appear once
Step-by-step execution:
-
Initialize:
s = {}
(empty set) -
Iteration 1:
x = 5
- Is 5 in set? No
- Add 5 to set:
s = {5}
- Continue
-
Iteration 2:
x = 1
- Is 1 in set? No
- Add 1 to set:
s = {5, 1}
- Continue
-
Iteration 3:
x = 5
- Is 5 in set? Yes!
- We found our duplicate!
- Return 5
The algorithm terminates early after checking only 3 elements out of 8. We didn't need to count how many times 5 appears - we just needed to detect that it appears more than once. Since the problem guarantees that only one element appears multiple times (exactly n
times), the first duplicate we find must be our answer.
Why this works: The mathematical constraints ensure that:
- If an element appears twice, it can't be one of the elements that appears exactly once
- Therefore, it must be the element that appears
n
times - No need to verify it appears exactly
n
times - the problem guarantees this
Solution Implementation
1class Solution:
2 def repeatedNTimes(self, nums: List[int]) -> int:
3 """
4 Find the element that appears N times in an array of size 2N.
5
6 Since there are 2N elements total and one element appears N times,
7 the other N elements must be unique. Therefore, the first duplicate
8 we encounter must be the element that appears N times.
9
10 Args:
11 nums: List of integers containing 2N elements
12
13 Returns:
14 The element that appears N times
15 """
16 # Set to track elements we've already seen
17 seen_elements = set()
18
19 # Iterate through each element in the array
20 for num in nums:
21 # If we've seen this element before, it must be the one repeated N times
22 if num in seen_elements:
23 return num
24
25 # Add the current element to our set of seen elements
26 seen_elements.add(num)
27
1class Solution {
2 public int repeatedNTimes(int[] nums) {
3 // Create a HashSet to store unique elements
4 // Initial capacity is set to n/2 + 1 for optimization
5 Set<Integer> seenNumbers = new HashSet<>(nums.length / 2 + 1);
6
7 // Iterate through the array
8 for (int i = 0; ; ++i) {
9 // Try to add current element to the set
10 // add() returns false if element already exists
11 if (!seenNumbers.add(nums[i])) {
12 // Found the duplicate element that appears n times
13 return nums[i];
14 }
15 }
16 }
17}
18
1class Solution {
2public:
3 int repeatedNTimes(vector<int>& nums) {
4 // Use a hash set to track elements we've seen
5 unordered_set<int> seen;
6
7 // Iterate through the array
8 for (int i = 0; ; ++i) {
9 // Check if current element has been seen before
10 if (seen.count(nums[i])) {
11 // If yes, this is the element that appears N times
12 return nums[i];
13 }
14 // Add current element to the set of seen elements
15 seen.insert(nums[i]);
16 }
17 }
18};
19
1/**
2 * Finds the element that appears N times in an array of size 2N
3 * where all other elements appear exactly once.
4 *
5 * @param nums - Array of integers with size 2N containing N+1 unique elements
6 * @returns The element that appears N times
7 */
8function repeatedNTimes(nums: number[]): number {
9 // Set to track elements we've already seen
10 const seenElements: Set<number> = new Set();
11
12 // Iterate through each element in the array
13 for (const currentElement of nums) {
14 // If we've seen this element before, it must be the repeated one
15 if (seenElements.has(currentElement)) {
16 return currentElement;
17 }
18 // Add the current element to our set of seen elements
19 seenElements.add(currentElement);
20 }
21
22 // This line should never be reached given the problem constraints
23 // TypeScript requires all code paths to return a value
24 return -1;
25}
26
Time and Space Complexity
Time Complexity: O(n)
where n
is the length of the input array nums
.
The algorithm iterates through the array once in the worst case. However, due to the problem's constraints (one element appears n/2
times in an array of length 2n
), the algorithm will typically terminate much earlier. By the pigeonhole principle, we're guaranteed to find a duplicate within the first n/2 + 1
elements, making the expected time complexity O(1)
but the worst-case remains O(n)
.
Space Complexity: O(n)
in the worst case.
The algorithm uses a set s
to store unique elements encountered during iteration. In the worst-case scenario, we might need to store up to n/2
elements before finding the repeated element (though practically this would be much less due to the problem constraints). Therefore, the space complexity is O(n)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Attempting to Calculate N First
A common mistake is trying to determine the value of n
first by calculating len(nums) // 2
, then attempting to count frequencies of all elements to find which one appears n
times. This approach is unnecessarily complex and inefficient.
Incorrect approach:
def repeatedNTimes(self, nums: List[int]) -> int:
n = len(nums) // 2
freq = {}
for num in nums:
freq[num] = freq.get(num, 0) + 1
if freq[num] == n:
return num
Why it's problematic: While this works, it's overly complicated and potentially slower since you might count all elements even after finding the answer.
2. Using List Instead of Set for Tracking
Some might use a list to track seen elements, which significantly degrades performance.
Inefficient approach:
def repeatedNTimes(self, nums: List[int]) -> int:
seen = []
for num in nums:
if num in seen: # O(n) operation for list lookup
return num
seen.append(num)
Why it's problematic: Checking membership in a list is O(n) for each lookup, making the overall time complexity O(n²) instead of O(n).
3. Edge Case: Assuming Element Distribution
Some solutions might assume the repeated element is evenly distributed or appears in specific positions, leading to solutions that work for most cases but fail on edge cases.
Risky optimization attempt:
def repeatedNTimes(self, nums: List[int]) -> int:
# Assuming the repeated element appears within first few elements
for i in range(4):
for j in range(i):
if nums[i] == nums[j]:
return nums[i]
Why it's problematic: While the repeated element often appears early due to probability, it's not guaranteed. For example, in [1,2,3,4,5,5]
, all repeated elements could be clustered at the end.
4. Not Returning Immediately Upon Finding Duplicate
Continuing to process after finding the duplicate wastes computational resources.
Suboptimal approach:
def repeatedNTimes(self, nums: List[int]) -> int:
seen = set()
repeated = None
for num in nums:
if num in seen:
repeated = num # Stores but doesn't return immediately
seen.add(num)
return repeated
Solution: Always return immediately when you find the first duplicate, as shown in the optimal solution. The mathematical constraints guarantee this first duplicate is the answer.
Which type of traversal does breadth first search do?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!