串联所有单词的子项

给定一个字符串 s 和一些长度相同的单词 words。 找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置

注意子串要与 words 中的单词完全匹配,中间不能有其他字符,不需要考虑 words 中单词串联的顺序。

思路:
    1. 用哈希表记录 words 中有哪些单词,以及出现的次数(检查每个s 子串时,哈希表都是新的)。
    
    2. 遍历一个s的子串,将其截成一个个单词的长度,去哈希表中查询。
    
    3. 如果出现在子串中的单词能在哈希表中找到,就将其数量 -1,对消掉一个。
    
    4. 如果单词在哈希表中找不到,或者数量为0,说明不符合要求,可以停止程序了
    
    5.若子串的单词都比较完毕,然后哈希表所有单词数量正常也都变成了0,就说明这个子串是我们要找的
    

var findSubstring = function(s, words) {
  // 由于works里每一项字符串的长度固定,故取出第一项的长度即可
  const wordSize = words[0].length
  // works里每一项字符串加一起的总长度
  const substringLen = wordSize * words.length
  
  // hashMap 记录下 每一项出现的次数
  // 最后wordsCount就像 --> { bar: 1, foo: 1}
  const wordsCount = {}
  words.forEach(w => (wordsCount[w] = (wordsCount[w] || 0) + 1))
  
  // 最后的结果
  const res = []
  
  // 若传入字符串的总长度 < 数组字符串的总长度,肯定不符合 return []
  
  // 总长度 - 数组字符串总长度,即为循环的次数
  
  for (let i = 0; i <= s.length - substringLen; i++) {
  
    //  每一次循环都需要复制hashMap
    const tempCount = {...wordsCount}
    
    // count 为数组有多少个字符串
    let count = words.length
    
    // 同时和数组字符串 截取再进行对比
    for (let j = i; j < i + substringLen; j += wordSize) {
      // 从0开始 截取字符串wordsize个字符串 判断是否在hashMap中
      const word = s.slice(j, j + wordSize)
  
      if (!(word in tempCount) || tempCount[word] <= 0) break
      // 在hashMap中将count减1 并且将hashMap中的值减一
      tempCount[word]--
      count--
    }
    // 有且只有在count === 0时 才说明可以完全拼成,并将当前的i导入
    if (count === 0) res.push(i)
  }
  return res
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值