hard Length of the Longest Valid Substring
Problem Statement
Given a string word and an array of strings forbidden, return the length of the longest valid substring of the string word.
A string is called valid if none of its substrings are present in a forbidden array.
A substring is defined as a contiguous sequence of characters in a string.
Examples
-
Example 1:
- Input:
word = "abracadabra",forbidden = ["cad", "abr"] - Expected Output:
5 - Justification: The longest valid substring without any forbidden substrings is "braca",which is 5 characters long.
- Input:
-
Example 2:
- Input:
word = "sunshine",forbidden = ["sun", "shine"] - Expected Output:
6 - Justification: The longest valid substring that does not include any forbidden substrings is "unshin", which is 6 characters long.
- Input:
-
Example 3:
- Input:
word = "openai",forbidden = ["pen", "ai"] - Expected Output:
3 - Justification: The longest valid substring avoiding the forbidden substrings is "ope", which is 3 characters long.
- Input:
Constraints:
- 1 <= word.length <= 105
- word consists only of lowercase English letters.
- 1 <= forbidden.length <= 105
- 1 <= forbidden[i].length <= 10
- forbidden[i] consists only of lowercase English letters.
Try it yourself
Try solving this question here:
✅ Solution Length of the Longest Valid Substring
Problem Statement
Given a string word and an array of strings forbidden, return the length of the longest valid substring of the string word.
A string is called valid if none of its substrings are present in a forbidden array.
A substring is defined as a contiguous sequence of characters in a string.
Examples
-
Example 1:
- Input:
word = "abracadabra",forbidden = ["cad", "abr"] - Expected Output:
5 - Justification: The longest valid substring without any forbidden substrings is "braca",which is 5 characters long.
- Input:
-
Example 2:
- Input:
word = "sunshine",forbidden = ["sun", "shine"] - Expected Output:
6 - Justification: The longest valid substring that does not include any forbidden substrings is "unshin", which is 6 characters long.
- Input:
-
Example 3:
- Input:
word = "openai",forbidden = ["pen", "ai"] - Expected Output:
3 - Justification: The longest valid substring avoiding the forbidden substrings is "ope", which is 3 characters long.
- Input:
Constraints:
- 1 <= word.length <= 105
- word consists only of lowercase English letters.
- 1 <= forbidden.length <= 105
- 1 <= forbidden[i].length <= 10
- forbidden[i] consists only of lowercase English letters.
Solution
To solve this problem, we will employ a sliding window approach combined with substring verification. This method involves expanding and contracting a window on the input string to find the longest segment that does not contain any of the forbidden substrings. The sliding window technique is chosen because it efficiently examines all possible substrings without redundant checks, making it ideal for this task.
Initially, we'll consider every possible starting point of a substring within the input string. For each start point, we'll expand the window to the right until we encounter a substring that matches any forbidden string. Upon finding such a match, we'll contract the window from the left to exclude the forbidden substring and continue the process. This approach ensures that we explore all potential substrings while skipping over invalid regions quickly, thereby identifying the maximum valid substring length.
Step-by-step Algorithm
- Initialize two pointers,
leftandright, to traverse the string.leftwill mark the start of the current substring, andrightwill mark the end. - Initialize a variable
maxLengthto keep track of the maximum length of valid substrings found. - Use a nested loop where the outer loop moves
leftfrom the beginning to the end of the string, and the inner loop expandsrightas long as the current substring does not contain any forbidden substrings.- For each position of
left, resetrighttoleftand incrementally expandrightto explore all possible substrings starting fromleft. - Check if the current substring (
word.substring(left, right + 1)) contains any forbidden substring. If it does, break the inner loop since expanding further will also include the forbidden substring. - Update
maxLengthif the length of the current valid substring (right - left) is greater than the currentmaxLength.
- For each position of
- Continue this process until all substrings have been examined.
- The final value of
maxLengthafter the loops complete is the length of the longest valid substring.
Algorithm Walkthrough
Let's consider the input word = "sunshine" and forbidden = ["sun", "shine"].
-
Initialize
maxLength: Start withmaxLengthset to 0. This variable will hold the length of the longest valid substring found that does not contain any forbidden substrings. -
First Iteration (
i = 0, starting with "s"):- Generate substrings starting from "s": "s", "su", "sun", "suns", "sunsh", "sunshi", "sunshin", "sunshine".
- "s" is valid, update
maxLengthto 1. - "su" is valid, update
maxLengthto 2. - "sun" is invalid (matches a forbidden word), break the inner loop.
- "s" is valid, update
- Generate substrings starting from "s": "s", "su", "sun", "suns", "sunsh", "sunshi", "sunshin", "sunshine".
-
Second Iteration (
i = 1, starting with "u"):- Generate substrings: "u", "un", "uns", "unsh", "unshi", "unshin", "unshine".
- "u" is valid, but no update since its length is less than
maxLength. - "un" is valid, but no update for the same reason.
- "uns" is valid, update
maxLengthto 3. - "unsh" is valid, update
maxLengthto 4. - "unshi" is valid, update
maxLengthto 5. - "unshin" is valid, update
maxLengthto 6. - "unshine" is invalid (contains "shine"), break the inner loop.
- "u" is valid, but no update since its length is less than
- Generate substrings: "u", "un", "uns", "unsh", "unshi", "unshin", "unshine".
-
Third Iteration (
i = 2, starting with "n"):- Generate substrings: "n", "ns", "nsh", "nshi", "nshin", "nshine".
- "n" is valid, but no update since its length is less than
maxLength. - Continue with "ns", "nsh", "nshi", "nshin", all valid but shorter than current
maxLength. - "nshine" is invalid (contains "shine"), break the inner loop.
- "n" is valid, but no update since its length is less than
- Generate substrings: "n", "ns", "nsh", "nshi", "nshin", "nshine".
-
Fourth Iteration (
i = 3, starting with "s"):- Generate substrings: "s", "sh", "shi", "shin", "shine".
- All substrings are valid until "shine", which is invalid. However, none are longer than the current
maxLengthof 6.
- All substrings are valid until "shine", which is invalid. However, none are longer than the current
- Generate substrings: "s", "sh", "shi", "shin", "shine".
-
Subsequent Iterations:
- For
i = 4(starting with "h") and onwards, all possible substrings are shorter than the currentmaxLengthor become invalid once "shine" is included.
- For
-
Fifth Iteration (
i = 4, starting with "h"):- Substrings: "h", "hi", "hin", "hine". None surpass the
maxLength.
- Substrings: "h", "hi", "hin", "hine". None surpass the
-
Sixth Iteration (
i = 5, starting with "i"):- Substrings: "i", "in", "ine". Again, none are longer than
maxLength.
- Substrings: "i", "in", "ine". Again, none are longer than
-
Seventh Iteration (
i = 6, starting with "n"):- Substrings: "n", "ne". Neither are longer than
maxLength.
- Substrings: "n", "ne". Neither are longer than
-
Eighth Iteration (
i = 7, starting with "e"):- Only substring: "e". Does not exceed
maxLength.
- Only substring: "e". Does not exceed
-
Conclusion:
maxLengthis finalized as 6.
Code
public class Solution {
// Method to find the length of the longest valid substring
public int findLengthOfLongestValidSubstring(
String word,
String[] forbidden
) {
int maxLength = 0; // Variable to store the maximum valid substring length found
// Iterate through each possible starting point of the substring
for (int left = 0; left < word.length(); ++left) {
// Iterate through each possible ending point of the substring
for (int right = left; right < word.length(); ++right) {
String currentSubstring = word.substring(left, right + 1);
// Break the inner loop if the current substring is forbidden
if (isForbidden(currentSubstring, forbidden)) break;
// Update the maxLength if the current substring is longer than previous ones
maxLength = Math.max(maxLength, right - left + 1);
}
}
return maxLength; // Return the length of the longest valid substring found
}
// Helper function to check if a substring contains any forbidden string
boolean isForbidden(String substring, String[] forbidden) {
for (String forb : forbidden) {
if (substring.contains(forb)) return true;
}
return false;
}
// Main method to test the functionality
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(
solution.findLengthOfLongestValidSubstring(
"abracadabra",
new String[] { "cad", "abr" }
)
); // Output: 5
System.out.println(
solution.findLengthOfLongestValidSubstring(
"sunshine",
new String[] { "sun", "shine" }
)
); // Output: 6
System.out.println(
solution.findLengthOfLongestValidSubstring(
"openai",
new String[] { "pen", "ai" }
)
); // Output: 3
}
}
Complexity Analysis
Time Complexity:
The primary operations of this algorithm involve iterating over all possible substrings of the input string word, which is of length n. For each substring, the algorithm checks if it contains any of the forbidden substrings. This check involves iterating through each forbidden substring that can, in the worst case, take
Space Complexity:
The space complexity is constant because the algorithm uses a fixed amount of extra space regardless of the input size.
🤖 Don't fully get this? Learn it with Claude
Stuck on Length of the Longest Valid Substring? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Length of the Longest Valid Substring** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Length of the Longest Valid Substring** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Length of the Longest Valid Substring**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Length of the Longest Valid Substring**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.