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

    For example, given:
    s"barfoothefoobarman"
    words["foo", "bar"]

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

    分析

    从s里面,找出由words里面的所有单词组成的字符子串(每个字符串仅出现一次),不要关注顺序。

    该题和 3.Longest Substring Without Repeatition 类似,都是维护一个窗口去滑动,记左边界 left,右边界right

    s长度 N
    words里单个单词长度 M,words单词总数 L
    那么对s遍历的右边界 last = N - M + 1

    在 hashmap 中存入 words 中的每个单词,key是单词,value单词出现在words中的index。 O(L)

    创建一个二维数组 table [2][L]
    0行:记录words中每个单词出现的次数。 O(L)
    1行:记录扫描时候,left和right之间窗口中,包含words的单词出现次数


    创建一个一维数组 smapping,遍历s,记录每个单词是否在 workds中。如果存在,则放入在words中的index;如果不存在,则为-1。 O(N)

    算法GIF解释:

    代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    class Solution {
    public:
        vector<int> findSubstring(string s, vector<string>& words) {
            int N = s.size();
            int M = words[0].size();
            int L = words.size();
            int last = N - M + 1;
            vector<int> result;
            unordered_map<string, int> mapping;
            vector<vector<int>> table(2,vector<int> (L));
     
            vector<int> smapping(last, -1);
     
            int index = 0, failures = 0;
            for (int i = 0; i < L; ++i) {
                auto word = mapping.find(words[i]);
                if (word == mapping.end()) {
                    failures++;
                    mapping.insert({ words[i], index++ });
                    word = mapping.find(words[i]);
                }
                table[0][word->second]++;
            }
     
            for (int i = 0; i < last; ++i) {
                auto word = mapping.find(s.substr(i, M));
                if (word != mapping.end()) {
                    smapping[i] = word->second;
                }
                else {
                    smapping[i] = -1;
                }
            }
     
            for (int i = 0; i < M; ++i) {
                int currentFailures = failures;
                fill(table[1].begin(), table[1].end(), 0);
                int L = i, R = i;
                while (R < last) {
                    while (currentFailures != 0 && R < last) {
                        if (smapping[R] != -1 && ++table[1][smapping[R]] == table[0][smapping[R]]) {
                            currentFailures--;
                        }
                        R += M;
                    }
     
                    while (currentFailures == 0 && L < R) {
                        if ((R - L) / M == words.size()) {
                            result.push_back(L);
                        }
                        if (smapping[L] != -1 && --table[1][smapping[L]] == table[0][smapping[L]] - 1) {
                            currentFailures++;
                        }
                        L += M;
                    }
                }
            }
            return result;
        }
    };


     





    附件列表

    • 相关阅读:
      iSeries存储过程笔记
      最近做得的网站
      两个iSeries存储过程的示例
      索引的怪异问题
      Saas的概念感触
      asp.net 2.0的TextBox遭遇ReadOnly=True时ViewState不回传的问题
      网上看到的一句诗
      DB2/400到Oracle的迁移
      如何往自己的网站增加Asp.net Ajax
      default关键字作用
    • 原文地址:https://www.cnblogs.com/zhxshseu/p/5df501ce21791b3c3cf3229bb03f5b23.html
    Copyright © 2011-2022 走看看