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

    Description

    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

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

    分析

    采用搜索的方法, 具体做法如下
       0 (预处理), 将 words 中中的所有单词用 26 进制转换为 数字
       1. 先统计 words 中所有单词中的 字母 个数, 然后 iter 输入字符串 ss。 找到一个窗口,其中所有的字符个数和  words 中一致。
       2. 窗口中的字符以 26 进制转换为数字, 和 words 中的数字表示进行比较。
    

    code

    class Solution(object):
        def findSubstring(self, ss, words):
            """
            :type s: str
            :type words: List[str]
            :rtype: List[int]
            """
            N, M, A = len(ss), len(words), ord('a')
            if N*M == 0:
                return []
            
            L = M * len(words[0])
            def build(word):
                s = 0
                for i in word:
                    s = s * 26 + ord(i) - A
                return s
    
            def build2(str):
                i = 0
                lWordN = []
                step = len(words[0])
                for i in range(0, len(str), step):
                    lWordN.append(build(str[i:i+step]))
                return sorted(lWordN)
            wordsNum = sorted([build(v) for v in words])
    
            if M*len(words[0]) > N:
                return []
            dp = [0 for i in range(26)]
            for v in words:
                for k in v:
                    dp[ord(k) - A] += 1
            for i, v in enumerate(dp):
                if v == 0:
                    dp[i] = -1
            s, e, ret, flag = 0, 0, [], False
            while N > e:
                if dp[ord(ss[e])-A]> - 1:
                    dp[ord(ss[e])-A] -= 1
                    s, e = e, e+1
                    break
                e += 1
            if e == N:
                if build2(ss[s:e+1]) == wordsNum:
                    ret.append(s)
                return ret
            
            while N > e:
                chn = ord(ss[e]) - A
                if dp[chn] == -1:
                    e += 1
                    flag = True
                    continue
                if flag:
                    while e > s:
                        s_key = ord(ss[s]) - A
                        s += 1
                        if dp[s_key] > -1:
                            dp[s_key] += 1
                    flag = False
                    # can be more fast if we can just reset array dp
    
                if dp[chn] == 0:
                    while e > s:
                        s_key = ord(ss[s]) - A
                        s += 1
                        if s_key == chn:
                            break
                        if dp[s_key] > -1:
                            dp[s_key] += 1
                    dp[chn] += 1
                dp[chn] -= 1
                if e - s +1 == L:
                    if build2(ss[s:e+1]) == wordsNum:
                        ret.append(s)
                e += 1
            return ret
    
    Runtime: 936 ms, faster than 36.72% of Python online submissions for Substring with Concatenation of All Words.
    速度上并不是很快,需要思考一波
    
  • 相关阅读:
    How to Automate IIS 7 Configuration with .NET
    windows phone 学习
    Redis VS. Memcached
    ROWNUM使用方法
    摘自----聊聊盛大的经验值
    理解Sql语句
    Odp.net 动态创建变量in
    ORACLE PLSQL DEVELOPER 中显示科学计数法
    http error 500.22 internal server error
    Resharper8 visual studio 中文版 快捷键无法使用
  • 原文地址:https://www.cnblogs.com/tmortred/p/13335911.html
Copyright © 2011-2022 走看看