前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >30. Substring with Concatenation of All Words

30. Substring with Concatenation of All Words

作者头像
Dylan Liu
发布2019-07-01 12:04:03
3720
发布2019-07-01 12:04:03
举报
文章被收录于专栏:dylanliu
Description

tag: Hash Table, Two Pointers, String difficulty: Hard

代码语言:javascript
复制
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 "barfoor" and "foobar" respectively.
The output order does not matter, returning [9,0] is fine too.

Note: 原题第二个例子中每个 word 的长度不一样,在此去掉

Solution

思路:建立一个map,遍历当前字符串, 当所有的 word 都出现过,记录当前位置,继续向后

代码语言:javascript
复制
func findSubstring(s string, words []string) []int {
    if len(words) == 0{
        return []int{}
    }
    wordsMap := make(map[string]int, len(words))

    for _,value := range words {
        wordsMap[value] = wordsMap[value] + 1
    }
    var result []int
    wordLen := len(words[0])
    bakWordsMap :=make(map[string]int, len(words))
    for i:=0;i<len(s);i++{
        for loc := i;loc<=len(s) - wordLen;loc+=wordLen{
            word := s[loc:loc+wordLen]
            if _,ok :=wordsMap[word];ok {
                bakWordsMap[word]= bakWordsMap[word] + 1
                wordsMap[word] = wordsMap[word] - 1
                if wordsMap[word] == 0{
                    delete(wordsMap, word)
                }
                
                if len(wordsMap) == 0 {
                    result = append(result, i)
                    break
                }
            } else {
                break
            }
        }
        for s,i := range bakWordsMap {
            wordsMap[s] = wordsMap[s] + i
        }
        bakWordsMap =make(map[string]int, len(words))
    }
    return result
}

遇到的问题:

  1. words 为空字符串问题
  2. words 中可以可以出现相同的单词

Note:

从这个题中才看出 go 的 map 操作很昂贵,看了其他人的提交,基本思路是一致的,但别人的运行时间只有12ms,而我这个是1993ms,修改了两次减少map的使用,运行时间就大幅减少,这是语言的问题,和方法无关,因此只优化了两次。

贴一下最后的优化,运行时间减少一半在900ms左右

代码语言:javascript
复制
func findSubstring(s string, words []string) []int {
    if len(words) == 0{
        return []int{}
    }
    wordsMap := make(map[string]int, len(words))

    for _,value := range words {
        wordsMap[value] = wordsMap[value] + 1
    }
    var result []int
    wordLen := len(words[0])
    bakWordsMap :=make(map[string]int)
    matchCount := len(words)
    for i:=0;i<len(s);i++{
        for loc := i;loc<=len(s) - wordLen;loc+=wordLen{
            word := s[loc:loc+wordLen]
            if v,ok :=wordsMap[word];ok && v>0 {
                bakWordsMap[word]= bakWordsMap[word] + 1
                wordsMap[word] = wordsMap[word] - 1
                matchCount--
                if matchCount == 0 {
                    result = append(result, i)
                    break
                }
            } else {
                break
            }
        }
        matchCount = len(words)
        for s,i := range bakWordsMap {
            wordsMap[s] = wordsMap[s] + i
        }
        bakWordsMap =make(map[string]int)
    }
    return result
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Description
  • Solution
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档