[LeetCode] 030. Substring with Concatenation of All Words (Hard) (C++/Java)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql)

Github: https://github.com/illuz/leetcode


030. Substring with Concatenation of All Words (Hard)

链接

题目:https://oj.leetcode.com/problems/substring-with-concatenation-of-all-words/

代码(github):https://github.com/illuz/leetcode

题意

给一个字符串 S 和一个单词列表,单词长度都一样,找出所有 S 的子串,子串由所有单词组成,返回子串的起始位置。

分析

很明显每个子串都是由所有单词组成的,长度是一定的,所以直接枚举子串,切分后再用 map 进行判断就行了。

这样的算法复杂度是 O(n*m),其实还有几种很酷的 O(n) 的算法:

  1. 「076. Minimum Window Substring (Hard)」 一样的思路,就是维护两个指针,分别为前后区间,和一个 map,跑前面的指针看看当前区间能不能恰好匹配,行的话就得到答案了。
  2. 还有个用神奇的 map<string, queue> 来做,其实原理是跟 1 是一样的,具体见:code with HashTable with Queue for O(n) runtime
  3. 这其实只是一个优化,在匹配时使用 Trie 匹配,具体见:Accepted recursive solution using Trie Tree

这里用 C++ 实现了 O(n*m) 算法,用 Java 实现了 1 算法。

代码

C++:

class Solution {
public:
    vector<int> findSubstring(string S, vector<string> &L) {
		map<string, int> words;
		map<string, int> curWords;
		vector<int> ret;
		int slen = S.length();
		if (!slen || L.empty()) return ret;
		int llen = L.size(), wlen = L[0].length();

		// record the current words map
		for (auto &i : L)
			++words[i];

		// check the [llen * wlen] substring
		for (int i = 0; i + llen * wlen <= slen; i++) {
			curWords.clear();
			int j = 0;
			// check the words
			for (j = 0; j < llen; j++) {
				string tmp = S.substr(i + j * wlen, wlen);
				if (words.find(tmp) == words.end())
					break;
				++curWords[tmp];
				if (curWords[tmp] > words[tmp])
					break;
			}
			if (j == llen)
				ret.push_back(i);
		}
		return ret;
    }
};

Java:

public class Solution {

    public List<Integer> findSubstring(String S, String[] L) {
        List<Integer> ret = new ArrayList<Integer>();
        int slen = S.length(), llen = L.length;
        if (slen <= 0 || llen <= 0)
            return ret;
        int wlen = L[0].length();

        // get the words' map
        HashMap<String, Integer> words = new HashMap<String, Integer>();
        for (String str : L) {
            if (words.containsKey(str)) {
                words.put(str, words.get(str) + 1);
            } else {
                words.put(str, 1);
            }
        }

        for (int i = 0; i < wlen; ++i) {
            int left = i, count = 0;
            HashMap<String, Integer> tmap = new HashMap<String, Integer>();

            for (int j = i; j <= slen - wlen; j += wlen) {
                String str = S.substring(j, j + wlen);

                if (words.containsKey(str)) {
                    if (tmap.containsKey(str)) {
                        tmap.put(str, tmap.get(str) + 1);
                    } else {
                        tmap.put(str, 1);
                    }

                    if (tmap.get(str) <= words.get(str)) {
                        count++;
                    } else {
                        // too many words, push the 'left' forward
                        while (tmap.get(str) > words.get(str)) {
                            String tmps = S.substring(left, left + wlen);
                            tmap.put(tmps, tmap.get(tmps) - 1);
                            if (tmap.get(tmps) < words.get(tmps)) {
                                // if affect the count
                                count--;
                            }
                            left += wlen;
                        }
                    }

                    // get the answer
                    if (count == llen) {
                        ret.add(left);
                        // it's better to push forward once
                        String tmps = S.substring(left, left + wlen);
                        tmap.put(tmps, tmap.get(tmps) - 1);
                        count--;
                        left += wlen;
                    }
                } else {
                    // not any match word
                    tmap.clear();
                    count = 0;
                    left = j + wlen;
                }
            }
        }
        return ret;
    }
}
时间: 2024-11-10 11:49:19

[LeetCode] 030. Substring with Concatenation of All Words (Hard) (C++/Java)的相关文章

LeetCode 030 Substring with Concatenation of All Words

题目要求:Substring with Concatenation of All Words You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any i

[LeetCode] 30. 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 wordsexactly once and without any intervening characters. For example, give

LeetCode 30 Substring with Concatenation of All Words (C,C++,Java,Python)

Problem: 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 wordsexactly once and without any intervening characters. For exam

030 Substring with Concatenation of All Words

030 Substring with Concatenation of All Words 用一个dictiionary来记录当前对应还有多少需要match的word. dict.copy()用来copy dictionary. from collections import defaultdict class Solution: # @param {string} s # @param {string[]} words # @return {integer[]} def findSubstri

leetCode 30.Substring with Concatenation of All Words (words中全部子串相连) 解题思路和方法

Substring with Concatenation of All Words 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 an

leetCode 30.Substring with Concatenation of All Words (words中所有子串相连) 解题思路和方法

Substring with Concatenation of All Words 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 an

【leetcode】Substring with Concatenation of All Words

Substring with Concatenation of All Words You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any interv

leetcode 之 Substring with Concatenation of All Words

Substring with Concatenation of All Words You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any interv

LeetCode 30 Substring with Concatenation of All Words(与所有文字串联子串)(*)

翻译 给定一个字符串S,一个单词的列表words,全是相同的长度. 找到的子串(多个)以s即每个词的字串联恰好一次并没有任何插入的字符所有的起始索引. 原文 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