zoukankan      html  css  js  c++  java
  • Leetcode#30 Substring with Concatenation of All Words

    原题地址

    将L中的单词看成一个整体,这道题与Minimun Window String比较类似,都是利用滑动窗口搜索。

    所以,依次枚举所有S的起始位置i,从i处开始搜索。当然并不需要枚举所有的i,i最多等于L中单词长度-1。比如L中的单词长度为3,那么当枚举过i=0,1,2后,不用再尝试i=3了,因为结果已经被i=0的情况覆盖过了。

    用左右两个指针(left,right)分别指向窗口的左右边界,按如下规则移动指针:

    1. 拓展窗口。不妨设right指向的单词是w,观察w:

    如果w不在L中,重置窗口,让窗口跨过w,即right++, left = right

    否则,不妨设w在窗口中出现的次数是window[w],w在L中出现的次数为traits[w]。

    如果window[w] < traits[w],说明这个单词还不够呢,那么拓展窗口,将right右移一个单位,别忘了window[w]++

    如果window[w] == traits[w],说明当前窗口可能构成了一组解,那么停止扩展窗口,跳至第3步(检查)。

    如果window[w] > traits[w],说明w出现次数太多了,不能都放在窗口里,那么停止扩展窗口,跳至第2步(收缩窗口),目的是把多余的w排出窗口。

    2. 收缩窗口。第1步保证了此时遇到的单词一定都是出现在L中的。

    走到这里说明一定是哪个单词多了,不妨假设就是w,那么不断右移left收缩窗口,每次window[*left]--,直到window[w] == traits[w],结束收缩

    3. 检查是否是一组解

    这一步很简单,看一下窗口长度是否等于L的长度和即可,因为前面两步保证了任意单词w一定出现在L中,并且window[w] <= traits[w]。如果是解,加入结果集中。

    之后返回第1步,继续下一个轮回,直到窗口移动到S右边界。

    代码:

     1 vector<int> findSubstring(string S, vector<string> &L) {
     2   vector<int> res;
     3   map<string, int> traits;
     4 
     5   if (L.empty() || S.empty()) return res;
     6 
     7   for (auto s : L)
     8     traits[s]++;
     9   int len = L[0].length();
    10 
    11   for (int i = 0; i < len; i++) {
    12     map<string, int> window;
    13 
    14     int l = i;
    15     int r = i;
    16     while (r < S.length()) {
    17       while (r < S.length()) {
    18         string word = S.substr(r, len);
    19         r += len;
    20         if (traits.find(word) == traits.end()) {
    21           window.clear();
    22           l = r;
    23         }
    24         else {
    25           window[word]++;
    26           if (window[word] >= traits[word])
    27             break;
    28         }
    29       }
    30       while (l < r) {
    31         string head = S.substr(l, len);
    32         string tail = S.substr(r - len, len);
    33         if (window[tail] == traits[tail])
    34           break;
    35         l += len;
    36         window[head]--;
    37       }
    38       if (r - l == len * L.size()) {
    39         res.push_back(l);
    40       }
    41     }
    42   }
    43 
    44   return res;
    45 }
  • 相关阅读:
    WPF PrismDialog PopupWindowAction使用MetroWindow
    WPF 定义Lookless控件的默认样式、 OnApplyTemplate 如何使用(实现方式、如何工作的)!
    WPF MeasureOverride和 ArrangeOverride做个 页面导航
    MeasureOverride和ArrangeOverride 练手项目
    XAML 调试工具 不见了?
    未能加载文件或程序集,PublicKeyToken=“**********”,或它的某一个依赖项。强名称验证失败。
    .NET 中的 GAC
    软考过程知识整理记录
    定时执行exe、windows任务计划、windows服务
    为视图或函数指定的列名比其定义中的列多。
  • 原文地址:https://www.cnblogs.com/boring09/p/4242416.html
Copyright © 2011-2022 走看看