Repeated DNA Sequences — LeetCode #187 (Medium)
Tags: Hash Table, String, Bit Manipulation, Sliding Window, Rolling Hash, Hash Function
Related patterns: Hash Map, Sliding Window
Brute Force approach
Time complexity: O(n²). Space complexity: O(n).
The brute force approach involves generating all possible 10-letter-long substrings from the DNA sequence and checking for duplicates. This is straightforward but inefficient for large strings.
The time complexity is O(n²) because we potentially check every substring against all previously seen substrings. The space complexity is O(n) for storing seen sequences.
- Step 1: Initialize an empty list to store repeated sequences.
- Step 2: Use a nested loop to generate all possible 10-letter-long substrings.
- Step 3: Use a set to track seen substrings and add duplicates to the list.
1. Input: s = 'AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT'
2. Initialize seen = {}, output = {}
3. i = 0, seq = 'AAAAACCCCC', seen = {'AAAAACCCCC'}
4. i = 1, seq = 'AAAACCCCCA', seen = {'AAAAACCCCC', 'AAAACCCCCA'}
5. i = 2, seq = 'AAACCCCCAA', seen = {'AAAAACCCCC', 'AAAACCCCCA', 'AAACCCCCAA'}
6. i = 5, seq = 'CCCCCAAAAA', seen = {'AAAAACCCCC', 'AAAACCCCCA', 'AAACCCCCAA', 'CCCCCAAAAA'} (output now contains 'AAAAACCCCC', 'CCCCCAAAAA')
Optimal Solution approach
Time complexity: O(n). Space complexity: O(n).
The optimal solution uses a sliding window approach with a hash set to track seen sequences efficiently. This reduces the time complexity significantly.
The time complexity is O(n) because we only traverse the string once. The space complexity is O(n) for storing the sequences in the sets.
- Step 1: Initialize two sets: one for seen sequences and one for output.
- Step 2: Loop through the string, extracting each 10-letter-long substring.
- Step 3: If the substring is already in the seen set, add it to the output set; otherwise, add it to the seen set.
1. Input: s = 'AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT'
2. Initialize seen = {}, output = {}
3. i = 0, seq = 'AAAAACCCCC', seen = {'AAAAACCCCC'}
4. i = 1, seq = 'AAAACCCCCA', seen = {'AAAAACCCCC', 'AAAACCCCCA'}
5. i = 5, seq = 'CCCCCAAAAA', seen = {'AAAAACCCCC', 'AAAACCCCCA', 'CCCCCAAAAA'} (output now contains 'AAAAACCCCC', 'CCCCCAAAAA')
6. Final output: ['AAAAACCCCC', 'CCCCCAAAAA']
Key Insights
- Using a set allows for O(1) average time complexity for insertions and lookups.
- The problem can be visualized as a sliding window of fixed size (10) moving through the string.
Common Mistakes
- Not considering edge cases where the string is shorter than 10 characters.
- Confusing the use of a set versus a list for tracking seen sequences.
Interview Tips
- Always clarify the constraints and edge cases before diving into coding.
- Think about the efficiency of your solution; discuss trade-offs between time and space complexity.
- Practice explaining your thought process as you code, as communication is key in interviews.