Advertisement

Substring with Concatenation of All Words - LeetCode 30 Solution

Substring with Concatenation of All Words - Complete Solution Guide

Substring with Concatenation of All Words is LeetCode problem 30, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

You are given a string s and an array of strings words . All the strings of words are of the same length . A concatenated string is a string that exactly contains all the strings of any permutation of words concatenated. For example, if words = ["ab","cd","ef"] , then "abcdef" , "abefcd" , "cdabef" , "cdefab" , "efabcd" , and "efcdab" are all concatenated strings. "acdbef" is not a concatenated string because it is not the concatenation of any permutation of words . Return an array of the starti

Detailed Explanation

The problem asks us to find all starting indices of substrings in a given string 's' that are formed by concatenating all the words from a given array 'words'. All words in the 'words' array have the same length. The order of words in the concatenated substring must match a permutation of the 'words' array. For instance, if words = ["ab","cd","ef"], then "abcdef", "abefcd", etc. are valid concatenated substrings, but "acdbef" is not. We should return a list of the starting indices of all such occurrences in 's'.

Solution Approach

The provided code uses a sliding window approach combined with hash tables to efficiently solve this problem. It iterates through the string 's' with a window of the size equal to the total length of the concatenated words. The core idea is to check for each possible starting position whether the substring of length `concat_len` can be formed by concatenating the words in `words`. To do this efficiently, it uses a hash map to store the counts of words in the original `words` array, and another hash map to track the counts of words within the current window. The outer loop iterates `wordLen` times to cover all possible offsets where a concatenated word might start, ensuring every potential substring is checked. The inner loop implements the sliding window, checking if words appear as expected and adjusting the window boundaries when necessary.

Step-by-Step Algorithm

  1. Step 1: Handle edge cases where 's' or 'words' are empty or invalid.
  2. Step 2: Calculate the length of each word, the number of words, and the total length of the concatenated string.
  3. Step 3: Create a hash table (word_counts) to store the counts of each word in the 'words' array.
  4. Step 4: Iterate 'word_len' times with 'r' from 0 to 'word_len' - 1. This loop essentially starts the search for concatenated words at every possible offset to cover all possible starting positions.
  5. Step 5: Initialize the left boundary 'left' to 'r' and create a hash table (words_seen) to track the words seen in the current window.
  6. Step 6: Iterate through the string 's' from 'r' with step 'word_len'. Extract a word (substring of length 'word_len') at each step.
  7. Step 7: If the extracted 'word' is present in 'word_counts', update the 'words_seen' counter. If the count of a particular word in 'words_seen' exceeds its count in 'word_counts', shrink the window from the left until the counts match. This ensures the window contains a valid concatenation.
  8. Step 8: If the length of the current window is equal to the total length of concatenated words ('concat_len'), add the starting index 'left' to the result list. This means a valid substring concatenation has been found.
  9. Step 9: If the extracted 'word' is not present in 'word_counts', clear the 'words_seen' counter and move the left boundary to the next possible position. This indicates the current window cannot be a valid concatenation.
  10. Step 10: Return the list of starting indices.

Key Insights

  • Insight 1: The core idea is to treat the problem as a sliding window. Since all words have the same length, we can move the window by the length of a word at a time.
  • Insight 2: We can use a hash table (or Counter in Python) to store the counts of each word in the 'words' array. This allows for efficient comparison when checking if a substring is a valid concatenation.
  • Insight 3: A naive approach could lead to TLE, so we must optimize the sliding window by only checking substrings of the exact length of the concatenation of all words and efficiently updating counts in the window.

Complexity Analysis

Time Complexity: O(n*m)

Space Complexity: O(m)

Topics

This problem involves: Hash Table, String, Sliding Window.

Companies

Asked at: Adobe, Amazon, Apple, Bloomberg, Media.net, Meta, Microsoft, Roku, Samsung, Zeta.