LeetCode 30 Substring with Concatenation of All Words(确定包含所有子串的起始下标)

Posted 伊甸一点

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 30 Substring with Concatenation of All Words(确定包含所有子串的起始下标)相关的知识,希望对你有一定的参考价值。

 
在字符串s中找到包含字符串数组words所有子串连续组合的起始下标(words中的子串排列顺序前后不计但是需要相连在s中不能存在其他字符)
 
 
参考代码 :
 
package leetcode_50;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/***
 * 
 * @author pengfei_zheng
 * 匹配words所有元素
 */

public class Solution30 {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> result = new ArrayList<Integer>();
        int wordLength = words[0].length(), patternLength = wordLength * words.length;
        if (patternLength > s.length()) {
            return result;
        }
        // array[0] stores the word count in the given pattern
        // array[1] stores the word count in the actual string
        int[][] wordCountArr = new int[2][words.length];

        // This map is used to maintain the index of the above array
        Map<String, Integer> wordCountIndexMap = new HashMap<String, Integer>();

        // storing the word counts in the given patter. array[0] is populated
        for (int i = 0, idx = 0; i < words.length; i++) {
            if (wordCountIndexMap.containsKey(words[i])) {
                wordCountArr[0][wordCountIndexMap.get(words[i])]++;
            } else {
                wordCountIndexMap.put(words[i], idx);
                wordCountArr[0][idx++]++;
            }
        }

        // this is required to cover use case when the given string first letter
        // doesnt corresponds to any matching word.
        for (int linearScan = 0; linearScan < wordLength; linearScan++) {
            int left = linearScan, right = linearScan, last = s.length() - wordLength, wordMatchCount = words.length;

            // reset word counts for the given string
            Arrays.fill(wordCountArr[1], 0);

            // this logic same as minimum window problem
            while (right <= last) {
                while (wordMatchCount > 0 && right <= last) {
                    String subStr = s.substring(right, right + wordLength);
                    if (wordCountIndexMap.containsKey(subStr)) {
                        int idx = wordCountIndexMap.get(subStr);
                        wordCountArr[1][idx]++;
                        if (wordCountArr[0][idx] >= wordCountArr[1][idx]) {
                            wordMatchCount--;
                        }
                    }

                    right += wordLength;
                }

                while (wordMatchCount == 0 && left < right) {
                    String subStr = s.substring(left, left + wordLength);
                    if (wordCountIndexMap.containsKey(subStr)) {
                        // this check is done to make sure the sub string has
                        // only the given words.
                        if ((right - left) == patternLength) {
                            result.add(left);
                        }

                        int idx = wordCountIndexMap.get(subStr);
                        // if this condition is satisfied, that means now we
                        // need to find the removed word in the remaining string
                        if (--wordCountArr[1][idx] < wordCountArr[0][idx]) {
                            wordMatchCount++;
                        }
                    }

                    left += wordLength;
                }
            }
        }

        return result;
    }
}

 

以上是关于LeetCode 30 Substring with Concatenation of All Words(确定包含所有子串的起始下标)的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 30 Substring with Concatenation of All Words

19.1.30 [LeetCode 30] Substring with Concatenation of All Words

LeetCode(30) Substring with Concatenation of All Words

LeetCode30. Substring with Concatenation of All Words

leetcode 30. Substring with Concatenation of All Words

LeetCode HashTable 30 Substring with Concatenation of All Words