You are given a string word and an integer k. Your task is to count the number of substrings of word that meet the following criteria:
-
Character Frequency: Each character in the substring must appear exactly
ktimes. -
Adjacent Characters: The absolute difference between the ASCII values of any two adjacent characters in the substring must be at most 2.
A substring is defined as a contiguous sequence of characters within the string word.
Write a function that returns the number of complete substrings.
Input: str = "igigee", k = 2
Output: 3
Input: str = "pdpddpdppd", k = 4
Output: 1
function countValidSubstrings(word, k) {
const length = word.length;
let count = 0;
// Function to check if all characters in the map appear exactly k times
function hasValidCharacterCounts(countMap) {
return Object.values(countMap).every(count => count === k);
}
// Iterate over all possible substrings
for (let start = 0; start < length; start++) {
const frequencyMap = {};
for (let end = start; end < length; end++) {
const char = word[end];
frequencyMap[char] = (frequencyMap[char] || 0) + 1;
if (!hasValidCharacterCounts(frequencyMap)) {
continue;
}
if (end > start && Math.abs(word.charCodeAt(end) - word.charCodeAt(end - 1)) > 2) {
break; // As soon as the ASCII difference condition fails, break out of the loop
}
if (hasValidCharacterCounts(frequencyMap)) {
count++;
}
}
}
return count;
}function countValidSubstringsUsingSlidingWindow(word, k) {
function hasValidCharacterCounts(countMap) {
return Object.values(countMap).every(count => count === k);
}
let count = 0;
for (let start = 0; start < word.length; start++) {
const frequencyMap = {};
let isValid = true;
for (let end = start; end < word.length; end++) {
const char = word[end];
frequencyMap[char] = (frequencyMap[char] || 0) + 1;
if (!hasValidCharacterCounts(frequencyMap)) {
continue;
}
if (end > start && Math.abs(word.charCodeAt(end) - word.charCodeAt(end - 1)) > 2) {
isValid = false;
}
if (isValid && hasValidCharacterCounts(frequencyMap)) {
count++;
} else {
break;
}
}
}
return count;
}function countCompleteSubstringsWithDP(word, k) {
const length = word.length;
let count = 0;
for (let start = 0; start < length; start++) {
const frequencyMap = {};
let isValid = true;
for (let end = start; end < length; end++) {
const char = word[end];
frequencyMap[char] = (frequencyMap[char] || 0) + 1;
if (Object.values(frequencyMap).some(freq => freq > k)) {
isValid = false;
break;
}
if (Object.values(frequencyMap).every(freq => freq === k)) {
if (end > start && Math.abs(word.charCodeAt(end) - word.charCodeAt(end - 1)) > 2) {
isValid = false;
break;
}
if (isValid) {
count++;
}
}
}
}
return count;
}function countSubstringsWithPrefixFrequency(word, k) {
const length = word.length;
let count = 0;
for (let start = 0; start < length; start++) {
const frequencyMap = {};
let valid = true;
for (let end = start; end < length; end++) {
const char = word[end];
frequencyMap[char] = (frequencyMap[char] || 0) + 1;
if (Object.values(frequencyMap).some(count => count > k)) {
valid = false;
break;
}
if (Object.values(frequencyMap).every(count => count === k)) {
if (end > start && Math.abs(word.charCodeAt(end) - word.charCodeAt(end - 1)) > 2) {
valid = false;
break;
}
if (valid) {
count++;
}
}
}
}
return count;
}function countValidSubstringsWithAsciiCheck(word, k) {
const length = word.length;
let count = 0;
// Function to check if all characters in the map appear exactly k times
function hasValidCharacterCounts(countMap) {
return Object.values(countMap).every(count => count === k);
}
// Iterate over all possible starting points
for (let start = 0; start < length; start++) {
const frequencyMap = {};
let isValid = true;
for (let end = start; end < length; end++) {
const char = word[end];
frequencyMap[char] = (frequencyMap[char] || 0) + 1;
if (!hasValidCharacterCounts(frequencyMap)) {
// If frequency count fails, move to the next start position
continue;
}
// Check ASCII difference condition
if (end > start && Math.abs(word.charCodeAt(end) - word.charCodeAt(end - 1)) > 2) {
isValid = false;
}
if (isValid && hasValidCharacterCounts(frequencyMap)) {
count++;
} else {
break; // Early exit for current starting point if not valid
}
}
}
return count;
}function countSubstringsUsingHashSet(word, k) {
let count = 0;
for (let start = 0; start < word.length; start++) {
const frequencyMap = {};
let valid = true;
for (let end = start; end < word.length; end++) {
const char = word[end];
frequencyMap[char] = (frequencyMap[char] || 0) + 1;
if (Object.values(frequencyMap).some(count => count > k)) {
valid = false;
break;
}
if (Object.values(frequencyMap).every(count => count === k)) {
if (end > start && Math.abs(word.charCodeAt(end) - word.charCodeAt(end - 1)) > 2) {
valid = false;
break;
}
if (valid) {
count++;
}
}
}
}
return count;
}function countSubstringsWithSetValidation(word, k) {
const length = word.length;
let count = 0;
for (let start = 0; start < length; start++) {
const frequencyMap = {};
for (let end = start; end < length; end++) {
const char = word[end];
frequencyMap[char] = (frequencyMap[char] || 0) + 1;
if (Object.values(frequencyMap).every(count => count === k)) {
if (end > start && Math.abs(word.charCodeAt(end) - word.charCodeAt(end - 1)) > 2) {
break;
}
count++;
}
}
}
return count;
}function countSubstringsWithDirectValidation(word, k) {
const length = word.length;
let count = 0;
for (let start = 0; start < length; start++) {
const frequencyMap = {};
for (let end = start; end < length; end++) {
const char = word[end];
frequencyMap[char] = (frequencyMap[char] || 0) + 1;
if (Object.values(frequencyMap).some(count => count > k)) {
break;
}
if (Object.values(frequencyMap).every(count => count === k)) {
if (end > start && Math.abs(word.charCodeAt(end) - word.charCodeAt(end - 1)) > 2) {
break;
}
count++;
}
}
}
return count;
}function countSubstringsUsingTwoPointers(word, k) {
let count = 0;
for (let start = 0; start < word.length; start++) {
const frequencyMap = {};
for (let end = start; end < word.length; end++) {
const char = word[end];
frequencyMap[char] = (frequencyMap[char] || 0) + 1;
if (Object.values(frequencyMap).some(count => count > k)) {
break;
}
if (Object.values(frequencyMap).every(count => count === k)) {
if (end > start && Math.abs(word.charCodeAt(end) - word.charCodeAt(end - 1)) > 2) {
break;
}
count++;
}
}
}
return count;
}function countSubstringsWithEarlyExit(word, k) {
const length = word.length;
let count = 0;
for (let start = 0; start < length; start++) {
const frequencyMap = {};
let valid = true;
for (let end = start; end < length; end++) {
const char = word[end];
frequencyMap[char] = (frequencyMap[char] || 0) + 1;
if (Object.values(frequencyMap).some(count => count > k)) {
valid = false;
break;
}
if (Object.values(frequencyMap).every(count => count === k)) {
if (end > start && Math.abs(word.charCodeAt(end) - word.charCodeAt(end - 1)) > 2) {
valid = false;
break;
}
if (valid) {
count++;
}
}
}
}
return count;
}