• 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
  • 相关阅读:
    NGUI Sprite 和 Label 改变Layer 或父物体后 未更新深度问题
    unity销毁层级物体及 NGUI 深度理解总结
    unity 2d 和 NGUI layer
    关于NGUI与原生2D混用相互遮盖的问题心得
    CentOS7为firewalld添加开放端口及相关操作
    Python 操作redis有序集合(sorted set)
    win10下安装redis 服务
    python2/3中 将base64数据写成图片,并将图片数据转为16进制数据的方法、bytes/string的区别
    解决最小化安装Centos7后无法上网的问题,以及安装成功后的基本配置
    在mysql中使用group by和order by取每个分组中日期最大一行数据,亲测有效
  • 原文地址:https://www.cnblogs.com/yalphait/p/10339505.html
Copyright © 2020-2023  润新知