zoukankan      html  css  js  c++  java
  • Leetcode | 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 intervening characters.

    For example, given:
    S: "barfoothefoobarman"
    L: ["foo", "bar"]

    You should return the indices: [0,9].
    (order does not matter).

    这题真是自作孽不可活啊。一直想用动态规划去做,但是一旦L里面有重复词就很麻烦。花了几个小时还是没做出来啊。。。我可怜的周末。

    网上一看,原来就是扫描每一个位置,从该位置开始对每个单词计数。map里面存的是每个单词出现的次数(可能大于1)。

    注意点:

    1. S.length()返回值是size_t,如果直接用S.length()-int的话,负数会被转成很大的数;所以以后记得取字符串大小时,用一个int先来存。(Line 9);

    2. 用一个map统计word list中每个单词出现的次数; (Line 10-13)

    3. 从第i个位置开始,用一个map来统计每个单词出现的次数,该次数不能超过第2步得到的次数;(Line 19);

    4. 如果最终合法的单词总数等于L.size()的话,把i存到结果中;(Line 25)。

    5. Line 14 不减去wholeLen会出现TLE.

     1 class Solution {
     2 public:
     3     vector<int> findSubstring(string S, vector<string> &L) {
     4         vector<int> ret;
     5         if (S.empty()) return ret;
     6         if (L.empty()) return ret;
     7         int len = L[0].size();
     8         int wholeLen = len * L.size();
     9         int n = S.length();
    10         map<string, int> wordCount;
    11         for (int j = 0; j < L.size(); ++j) {
    12             wordCount[L[j]]++;
    13         }
    14         for (int i = 0; i <= n - wholeLen; ++i) {
    15             string tmp = S.substr(i, len);
    16             int pos = i;
    17             int c = 0;
    18             map<string, int> exist;
    19             while (wordCount.count(tmp) > 0 && exist[tmp] < wordCount[tmp]) {
    20                 c++;
    21                 pos += len;
    22                 exist[tmp]++;
    23                 tmp = S.substr(pos, len);
    24             }
    25             if (c == L.size()) ret.push_back(i);
    26         }
    27         return ret;
    28     }  
    29 };

     事实上用dfs应该也可以,原理上是一样的,而且后面的不够长的位置就不用检查了。但是会出现MLE.

    第三次写简洁许多。一次过。

     1 class Solution {
     2 public:
     3     vector<int> findSubstring(string S, vector<string> &L) {
     4         vector<int> ans;
     5         if (L.empty() || S.empty()) return ans;
     6         unordered_map<string, int> counts, appeared;
     7         for (auto str : L) {
     8             counts[str]++;
     9         }
    10         int len = L[0].length(), whole = len * L.size(), n = S.length();
    11         for (int start = 0; start + whole <= n; start++) {
    12             appeared.clear();
    13             bool found = true;
    14             for (int i = 0; i < whole && start + i < n; i += len) {
    15                 string tmp = S.substr(start + i, len);
    16                 appeared[tmp]++;
    17                 if (counts.count(tmp) < 0 || appeared[tmp] > counts[tmp]) {
    18                     found = false;
    19                     break;
    20                 }
    21             }
    22             if (found) ans.push_back(start);
    23         }
    24         
    25         return ans;
    26     }
    27 };
  • 相关阅读:
    Binary Tree Zigzag Level Order Traversal
    Binary Tree Level Order Traversal
    Symmetric Tree
    Best Time to Buy and Sell Stock II
    Best Time to Buy and Sell Stock
    Triangle
    Populating Next Right Pointers in Each Node II
    Pascal's Triangle II
    Pascal's Triangle
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/linyx/p/3722054.html
Copyright © 2011-2022 走看看