Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Finding the longest Substring with At Least n Repeating Characters in JavaScript
We are required to write a JavaScript function that takes in a string as the first argument and a positive integer n as the second argument.
The string is likely to contain some repeating characters. The function should find out and return the length of the longest substring from the original string in which all characters appear at least n number of times.
For example, if the input string is 'kdkddj' and n is 2, the output should be 5 because the desired longest substring is 'kdkdd'.
Problem Understanding
Given a string and a number n, we need to find the longest contiguous substring where every character appears at least n times within that substring.
const str = 'kdkddj';
const num = 2;
console.log("Input string:", str);
console.log("Minimum frequency:", num);
Input string: kdkddj Minimum frequency: 2
Algorithm Approach
The solution uses a divide-and-conquer approach:
- Count frequency of each character in the string
- Find characters that appear less than n times
- Split the string by these "invalid" characters
- Recursively check each valid substring
- Return the maximum length found
Complete Solution
const longestSubstring = (str = '', num) => {
// Base case: if string is shorter than required frequency
if (str.length < num) {
return 0;
}
// Count frequency of each character
const map = {};
for (let char of str) {
if (char in map) {
map[char] += 1;
} else {
map[char] = 1;
}
}
// Find character with minimum frequency
const minChar = Object.keys(map).reduce((minKey, key) =>
map[key] < map[minKey] ? key : minKey
);
// If minimum frequency meets requirement, entire string is valid
if (map[minChar] >= num) {
return str.length;
}
// Split by invalid characters and filter valid substrings
const substrings = str.split(minChar).filter(subs => subs.length >= num);
if (substrings.length === 0) {
return 0;
}
// Recursively find maximum from all valid substrings
let max = 0;
for (let ss of substrings) {
max = Math.max(max, longestSubstring(ss, num));
}
return max;
};
// Test the function
const str = 'kdkddj';
const num = 2;
console.log(`Longest substring length: ${longestSubstring(str, num)}`);
Longest substring length: 5
Step-by-Step Execution
// Let's trace through the example
const str = 'kdkddj';
const num = 2;
// Character frequencies: k=2, d=3, j=1
// Character 'j' appears only once (less than 2)
// Split by 'j': ['kdkdd']
// 'kdkdd' has length 5 and all characters appear >= 2 times
console.log("Original string: 'kdkddj'");
console.log("Character frequencies:");
console.log("k: 2 times, d: 3 times, j: 1 time");
console.log("Split by 'j' (invalid char): ['kdkdd']");
console.log("Result: 5 (length of 'kdkdd')");
Original string: 'kdkddj' Character frequencies: k: 2 times, d: 3 times, j: 1 time Split by 'j' (invalid char): ['kdkdd'] Result: 5 (length of 'kdkdd')
Additional Test Cases
// Test with different inputs
const testCases = [
['aaabb', 3], // Should return 3 ('aaa')
['ababbc', 2], // Should return 5 ('ababb')
['weitong', 2] // Should return 0 (no valid substring)
];
testCases.forEach(([testStr, testNum], index) => {
const result = longestSubstring(testStr, testNum);
console.log(`Test ${index + 1}: "${testStr}" with n=${testNum} ? ${result}`);
});
Test 1: "aaabb" with n=3 ? 3 Test 2: "ababbc" with n=2 ? 5 Test 3: "weitong" with n=2 ? 0
Time Complexity
The time complexity is O(n * k) where n is the string length and k is the number of unique characters. In the worst case, this could be O(n²) when we have many recursive calls.
Conclusion
This divide-and-conquer solution efficiently finds the longest substring where all characters meet the minimum frequency requirement. The algorithm recursively eliminates invalid characters and processes valid substrings to find the optimal result.
