leetcode算法整理30串联所有单词的子串

LEETCODE算法注解30:
给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
首先,最初的想法是将words中的词全部组合,看s中是否有匹配的。但是这复杂度高的离谱,肯定超出时间限制。n为words的个数,s为字符串长度,复杂度为O(s*n!)。
第一种解法:利用hashmap
例如[tag,tad,best,word,best]这个例子在haspmap中的形式为
[tag,1]
[tad,1]
[best,2]
[word,1]
让当前字符串 tag tag tad best best word tag去匹配。
1>若字符串中单词未出现在hashmap中,则直接去匹配下一个单词。
2>单词匹配成功。将匹配成功的单词按照同样的方式存入hashmap2中。判断两个hashmap中匹配成功的单词的value值大小。如果hashmap1中的value值大于hashmap中的value值,代表此单词的匹配次数已经超过了words词组中给出的单词个数,其实是已经匹配失败了。
3>当全部正确匹配的个数已经等于words词组的个数时,就可以输出当前起始点了。
在这里插入图片描述
经过匹配到第二个tag时,
在这里插入图片描述
很明显第二次单词匹配虽然成功,但其实次数已经超出了words的次数,所以需要判断value值。
代码如下:

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> ans = new ArrayList<Integer>();
        int wordnumber = words.length;
        if(wordnumber==0) return ans;
        int wordlength = words[0].length();
        //将所有单词存入hmp1中
         HashMap<String, Integer> hmp1 = new HashMap<String, Integer>();
         for(int i=0;i<wordnumber;i++)
         {
            //getOrDefaul此方法的含义;如果hmp1中不含有words[i],返回默认值0,含有返回此值的value值。
            int value = hmp1.getOrDefault(words[i], 0);
            //hashmap不允许key值重复,会覆盖
            hmp1.put(words[i], value + 1);
         }
         //开始遍历s
         for(int i=0 ; i< s.length()+1-wordnumber*wordlength ; i++)
         {
            HashMap<String, Integer> hmp2 = new HashMap<String, Integer>();
             int num = 0;
             //while循环为满足一次匹配的条件
             while(num < wordnumber)
             {
                 //依次截取出一个单词
                 String simpleword = s.substring(i+num*wordlength,i+(num+1)*wordlength);
                 //成功匹配
                 if(hmp1.containsKey(simpleword))
                 {
                     //将匹配成功的单词存入hmp2中
                    int value = hmp2.getOrDefault(simpleword, 0);
                    hmp2.put(simpleword, value + 1);
                    //边界条件,防止重复出现单词的个数超出words中给出的重复单词个数
                    if(hmp2.get(simpleword) > hmp1.get(simpleword)) break;
                 }
                 else//匹配失败
                 {
                     break;
                 }
                 num++;
             }
             //输出条件,单词全部匹配成功,增加i;
              if(num == wordnumber) 
              {
                  ans.add(i);
              }
         }
         return ans;
    }
}

参考如下:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-6/
`

发布了5 篇原创文章 · 获赞 1 · 访问量 77

猜你喜欢

转载自blog.csdn.net/qq_39502383/article/details/104068981