LeetCode – Substring with Concatenation of All Words (Java)

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

For example, given: s="barfoothefoobarman" & words=["foo", "bar"], return [0,9].


This problem is similar (almost the same) to Longest Substring Which Contains 2 Unique Characters.

Since each word in the dictionary has the same length, each of them can be treated as a single character.

Java Solution

public List<Integer> findSubstring(String s, String[] words) {
    ArrayList<Integer> result = new ArrayList<Integer>();
        return result;
    //frequency of words
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    for(String w: words){
            map.put(w, map.get(w)+1);
            map.put(w, 1);
    int len = words[0].length();
    for(int j=0; j<len; j++){
        HashMap<String, Integer> currentMap = new HashMap<String, Integer>();
        int start = j;//start index of start
        int count = 0;//count totoal qualified words so far
        for(int i=j; i<=s.length()-len; i=i+len){
            String sub = s.substring(i, i+len);
                //set frequency in current map
                    currentMap.put(sub, currentMap.get(sub)+1);
                    currentMap.put(sub, 1);
                    String left = s.substring(start, start+len);
                    currentMap.put(left, currentMap.get(left)-1);
                    start = start + len;
                    result.add(start); //add to result
                    //shift right and reset currentMap, count & start point         
                    String left = s.substring(start, start+len);
                    currentMap.put(left, currentMap.get(left)-1);
                    start = start + len;
                start = i+len;
                count = 0;
    return result;
Category >> Algorithms >> Interview  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
String foo = "bar";

  1. Larry Okeke on 2016-3-16

    A simple to understand soluton.

    Just get every possible concatenation of words in words array, and check whether each occurs in the main string.
    if the result is not -1, we have an index of substring!

    import java.util.*;

    public class duplicate_substring{

    public static ArrayList allPossibleArrangements = new ArrayList();

    public static void main(String[] args){

    String[] arr = new String[] {"chinelo", "arukwe", "larry"};

    ArrayList words = new ArrayList(Arrays.asList(arr));

    String s = "chineloarukwelarryokekearukwechinelolarrytestinglarryarukwechinelo";

    permutate(words, new Stack(), arr.length);

    List solution = solution(allPossibleArrangements.toArray(new String[0]), s);



    public static List solution(String[] words, String s){

    //use combinatorial algorithm to get every possible concatenation of words

    //find the index of each derived word in s.

    StringBuilder build = new StringBuilder();

    ArrayList result = new ArrayList();

    for(int i = 0; i < words.length; i++){

    String currentConcatenation = words[i];






    return result;


    public static void permutate(List items, Stack permutation, int size) {

    /* permutation stack has become equal to size that we require */

    if(permutation.size() == size) {

    /* print the permutation */

    //System.out.println(Arrays.toString(permutation.toArray(new Integer[0])));

    String s = "";

    for(String str: permutation){





    /* items available for permutation */

    String[] availableItems = items.toArray(new String[0]);

    for(String i : availableItems) {

    /* add current item */


    /* remove item from available item set */


    /* pass it on for next permutation */

    permutate(items, permutation, size);

    /* pop and put the removed item back */





  2. Ahmad El-Qaoud on 2016-11-14

    I solved by a better solution which happens to be more clear and has a better performance using the indexOf method and comparing the indices as follows:

    public static List searchIndecies(String s, String arr[]) {

    if (s == null || s.length() == 0 || arr == null || arr.length == 0) {
    return null;
    int wordLength = arr[0].length();
    List returnedIndecies = new ArrayList();
    List indecies = new ArrayList();
    for (int i = 0; i < s.length(); i++) {
    for (int m = 0; m < arr.length; m++) {
    int index = s.indexOf(arr[m], i);
    if (index != -1) {
    boolean validSeq = false;
    for (int n = 1; n < indecies.size() && indecies.size() == arr.length; n++) {
    if (indecies.get(n – 1) != indecies.get(n) – wordLength) {//Comparing indices based on words same length
    i = i + wordLength – 1;
    } else {
    i = indecies.get(n);
    validSeq = true;
    if (validSeq) {

    return returnedIndecies;


  3. Derek on 2017-7-26

    why is the first loop from 0 to length of the longest word.

    for(int j=0; j<len; j++)

    Why isn't this 0 to the length of the input string s? I'm guessing that you want to find all possibilities with the search starting at each index of the input string. well 0 to the length of the input string

    for(int j=0; j<s.length()-len; j++)
    for(int i=j; i<=s.length()-len; i=i+len)


Leave a comment