From Brute Force to Index-Based Frequency Thinking
At first glance, Contains Duplicate II looks simple:
βCheck if a number repeats within distance k.β
My first solution worked β but it was slow.
This article shows:
- My initial brute-force thinking
- Why simple frequency count is not enough
- The optimized approach using a hash map
- A debugger-style explanation of the tricky lines
π§© Problem Summary
You are given:
An array nums
An integer k
Return true if there exist two equal values such that
the absolute difference of their indices β€ k.
β My First Approach (Brute Force) Idea
- Check every pair (i, j) and see if
- values are equal
- index difference β€ k
Code
class Solution {
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
for(int i = 0; i < nums.size(); i++) {
for(int j = i + 1; j < nums.size(); j++) {
if(nums[i] == nums[j] && abs(i - j) <= k)
return true;
}
}
return false;
}
};
Problem β
Time complexity: O(nΒ²)
TLE for large inputs
π€ Can We Use Frequency Count?
Short answer: Not directly
A normal frequency map only tells:
2 β appears 3 times
But this problem asks:
HOW CLOSE are the indices?
So we need:
Last seen index, not count. This is the key insight π
β Optimized Idea (Index-Based Frequency)
Instead of counting occurrences. Store last index where a number appeared
Data structure:
unordered_map<int, int> lastIndex;
Meaning:
number β last index seen
π» Full Working C++ Code (With main)
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
bool containsNearbyDuplicate(vector<int>& nums, int k) {
unordered_map<int, int> lastIndex;
for (int i = 0; i < nums.size(); i++) {
// Check if number already exists
if (lastIndex.count(nums[i]) && i - lastIndex[nums[i]] <= k)
return true;
// Update last seen index
lastIndex[nums[i]] = i;
}
return false;
}
int main() {
vector<int> nums = {1, 2, 3, 1};
int k = 3;
cout << (containsNearbyDuplicate(nums, k) ? "true" : "false");
return 0;
}
π Debugger-Style Explanation (Line by Line)
The Tricky Line π
if (lastIndex.count(nums[i]) && i - lastIndex[nums[i]] <= k)
Letβs break it slowly.
πlastIndex.count(nums[i])
π IMPORTANT CLARIFICATION
β count() does NOT count frequency
It only checks existence.Returns 1 β key exists. Returns 0 β key does not exist
So this line means:
Have I seen nums[i] before? . Nothing more.
πlastIndex[nums[i]]
This holds:
The LAST index where nums[i] appeared
Example:
nums = [1, 2, 3, 1]
index = 3
Map before checking:
1 β 0
2 β 1
3 β 2
So:
lastIndex[1] = 0
πi - lastIndex[nums[i]]
This calculates:
current index - previous index
Example:
i = 3
lastIndex[1] = 0
distance = 3 - 0 = 3
This is exactly what the problem asks.
π Full Condition in Plain English
if (
"I have seen this number before"
AND
"distance between indices β€ k"
)
β return true.
π Visualization
For:
nums = [1, 2, 3, 1], k = 3
| i | nums[i] | lastIndex before | distance | result |
|---|---|---|---|---|
| 0 | 1 | not found | β | store 1 β 0 |
| 1 | 2 | not found | β | store 2 β 1 |
| 2 | 3 | not found | β | store 3 β 2 |
| 3 | 1 | found (0) | 3 | β true |
β What I Learned Now
- count() only checks existence
- Hash maps can store indices, not just counts
- Frequency count β position tracking
- This is a single-pass O(n) solution
β What I Didnβt Know Before
- That distance problems need index memory
- That frequency maps can mean different things
- Why brute force fails even when logic is correct
π― Final Takeaway
When a problem mentions distance between indices,
counting is not enough β track positions.
This pattern appears again in:
Longest substring without repeating characters
Sliding window problems
Index-based hashing questions
Top comments (1)
π Debugger-Style Explanation is nice to comprehend
the pivotal line
if (lastIndex.count(nums[i]) && i - lastIndex[nums[i]] <= k)Explanation in Plain English is more humane
Some comments may only be visible to logged-in visitors. Sign in to view all comments.