leetcode_30:串联所有单词的子串

先看一下我的战况,看看那三个七分钟…,没办法着急了受,其实大部分时间就是花在了调边界条件上了。
在这里插入图片描述
然后说一下思路吧:其实就是使用空间换取时间,但是我的时间没有很低,反而空间比我想象的要低一些。步骤如下:

  1. 我们把words中的所有单词放到哈希表中,其中的键为每个单词,值为单词的次数
  2. 然后我们遍历这个字符串s,而且每次遍历的子串长度都应该和words数组中所有字符串长度的总和一样,即words.length * words[0].length()
  3. 然后我们对子串中每个长度为words[0].length的单词进行检查,看看哈希表里面是否有它,或者它是不是已经出现过了:如果没有则直接break,这个子串不符合;如果有而且对应的出现次数大于0,则将出现次数减1
  4. 一直到最后如果子串中的每个单词都符合,那么就将这个子串的开始索引放到结果中。否则检查下一个子串。

代码如下:

    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> result = new ArrayList<>();
        if (s.equals("") || words.length == 0)	//被这个
            return result;
        Map<String, Integer> flag = new HashMap<>();
        reset(flag, words);		//将所有单词和对应出现次数放进去。
        int StrLength = words.length * words[0].length();	//要遍历的子串长度
        int head = 0, tail = StrLength, wordLength = words[0].length();	//两个指针指向子串的头和尾
        if (wordLength > s.length())	//如果字符串的长度还不如子串长,那么直接返回
            return result;
        while (tail <= s.length()) {	//开始遍历
            int index = head;
            for (index = head; index < tail; index += wordLength) {	//对于子串中的每个单词
                String curStr = s.substring(index, index+wordLength);	//获取单词
                if (!flag.containsKey(curStr) || flag.get(curStr) <= 0) {   //单词没有,或者有这个单词但是已经访问过了,不行
                    break;
                } else {
                    flag.put(curStr, flag.get(curStr)-1);   //出现次数减1
                }
            }
            if (index == tail) {	//遍历到了最后说明都符合,则把head加到结果集中
                result.add(head);
            }
            head++;		//此处子串的前进步长为1
            tail++;
            reset(flag, words);     //每次遍历完一个子串,都要重置访问标志
        }

        return result;
    }

    private void reset(Map<String, Integer> flag, String[] words) {
    	//因为上次遍历后可能flag里面还有一些没访问到,不为0,所以先将出现次数全置为0,然后再统计出现次数。
        for (String word : words) {
            if (flag.containsKey(word)) {
                flag.put(word, 0);  //要重置0
            }
        }
        for (int i = 0; i < words.length; ++i)
            if (flag.containsKey(words[i])) {
                flag.put(words[i], flag.get(words[i])+1);   //已经有了,则个数加1
            } else {
                flag.put(words[i], 1);  //否则只放1个
            }
    }
发布了96 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/reachwang/article/details/103437373