zoukankan      html  css  js  c++  java
  • 19.1.30 [LeetCode 30] 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 any intervening characters.

    Example 1:

    Input:
      s = "barfoothefoobarman",
      words = ["foo","bar"]
    Output: [0,9]
    Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively.
    The output order does not matter, returning [9,0] is fine too.
    

    Example 2:

    Input:
      s = "wordgoodgoodgoodbestword",
      words = ["word","good","best","word"]
    Output: []

    题意

    给定字符串s和字符串数组words,对于words中所有字符串任意顺序组合而成的字符串,如果是s的子串的求出在s中出现的所有索引。

    题解

    一开始暴力TLE了

     1 class Solution {
     2 public:
     3     set<int>ans;
     4     void findstr(string s,string now,deque<string>&words) {
     5         if (words.empty()) {
     6             int idx = s.find(now), base = 0;
     7             while (idx != string::npos) {
     8                 ans.insert(idx+base);
     9                 base = base + idx + 1;
    10                 s=s.substr(idx + 1);
    11                 idx = s.find(now);
    12             }
    13             return;
    14         }
    15         int size = words.size();
    16         for (int i = 0; i < size; i++) {
    17             string tmp = words[size-1];
    18             words.pop_back();
    19             findstr(s, now + tmp, words);
    20             words.push_front(tmp);
    21         }
    22         return;
    23     }
    24     vector<int> findSubstring(string s, vector<string>& words) {
    25         if (s == "" || words.size() == 0)return vector<int>();
    26         deque<string>wwords;
    27         for (int i = 0; i < words.size(); i++)
    28             wwords.push_back(words[i]);
    29         findstr(s, "", wwords);
    30         return vector<int>(ans.begin(),ans.end());
    31     }
    32 };
    View Code

     后来搞了种非常混乱的方法,类似于之前有道题的滑动窗口(要看清所有单词都是相同长度的,不然是想不到这种方法的……我一开始就没看见……)

    具体就是:

    单词长度:l,s长度:sl

    每次选定一个值为0~l-1的起始指针,初始尾指针与头指针重合,然后每次判断目前指向的那个单词(指针处于这个单词的头部)如果加进目前头尾指针形成的字符串中是否合法,如果合法就把尾指针后移l,否则把头指针移到尾指针后面。

    滑动窗口还算是蛮有趣蛮有用的一个思想吧

     1 class Solution {
     2 public:
     3     vector<int>contained, cnt, id;
     4     map<string, int>idx;
     5     int l;
     6     vector<int> findSubstring(string s, vector<string>& words) {
     7         if (s == "" || words.size() == 0)return vector<int>();
     8         vector<int>ans;
     9         contained.resize(words.size());
    10         cnt.resize(words.size());
    11         id.resize(s.length());
    12         sort(words.begin(), words.end());
    13         for (int i = 0; i < contained.size(); i++) {
    14             contained[i] = 0;
    15             cnt[i] = 0;
    16             idx.insert(make_pair(words[i], i));
    17             cnt[idx[words[i]]]++;
    18         }
    19         int leng = s.length();
    20         l = words[0].size();
    21         for (int i = 0; i < leng; i++) {
    22             if (idx.find(s.substr(i, l)) != idx.end())
    23                 id[i] = idx[s.substr(i, l)];
    24             else id[i] = -1;
    25         }
    26         for (int i = 0; i < l; i++) {
    27             int S = i;
    28             for (int j = i; j < leng; j += l) {
    29                 int now = id[j];
    30                 if (now == -1) {
    31                     while (S < j) {
    32                         contained[id[S]]--;
    33                         S += l;
    34                     }
    35                     S += l;
    36                     continue;
    37                 }
    38                 while (contained[now] >= cnt[now]) {
    39                     contained[id[S]]--;
    40                     S += l;
    41                 }
    42                 contained[now]++;
    43                 if (j - S + l == l * words.size())
    44                     ans.push_back(S);
    45             }
    46             for (int j = 0; j < contained.size(); j++)
    47                 contained[j] = 0;
    48         }
    49         return ans;
    50     }
    51 };
    View Code
  • 相关阅读:
    关于HashMap的线程安全问题
    Java利器之UML类图详解
    mongoDB4.0数据库
    requests-html库render的使用
    爬虫最新的库requests-html库总结
    爬虫多次爬取时候cookie的存储用于登入
    requests模块响应体属性和方法重新整理
    Visual Studio 代码补全功能有时候会失效的原因
    C++Primer笔记——文本查询程序(原创,未使用类)
    Clion 常用快捷键
  • 原文地址:https://www.cnblogs.com/yalphait/p/10339505.html
Copyright © 2011-2022 走看看