• leetcode-30


    首先一个很朴素的解法

    public class Solution30 {
        public static List<Integer> findSubstring(String s, String[] words) {
            List<Integer> res = new ArrayList<>();
            int wordNum = words.length;
            if (wordNum == 0) {
                return res;
            }
            int wordLen = words[0].length();
            Map<String, Integer> allWords = new HashMap<>();
            for (String w : words) {
                int value = allWords.getOrDefault(w, 0);
                allWords.put(w, value + 1);
            }
            for (int i = 0; i < s.length() - wordLen * wordNum + 1; i++) {
                Map<String, Integer> hasWords = new HashMap<>();
                int num = 0;
                while (num < wordNum) {
                    String word = s.substring(i + num * wordLen, i + (num + 1) * wordLen);
                    if (allWords.containsKey(word)) {
                        int value = hasWords.getOrDefault(word, 0);
                        hasWords.put(word, value + 1);
                        if (hasWords.get(word) > allWords.get(word)) {
                            break;
                        }
                    } else {
                        break;
                    }
                }
                if (num == wordNum) {
                    res.add(i);
                }
            }
            return res;
        }
    }

    看起来好像重复移动很多,优化一下

    这里强烈推荐https://leetcode.wang/

    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/

    public class Solution30 {
        public List<Integer> findSubstring(String s, String[] words) {
            List<Integer> res = new ArrayList<Integer>();
            int wordNum = words.length;
            if (wordNum == 0) {
                return res;
            }
            int wordLen = words[0].length();
            HashMap<String, Integer> allWords = new HashMap<String, Integer>();
            for (String w : words) {
                int value = allWords.getOrDefault(w, 0);
                allWords.put(w, value + 1);
            }
            //将所有移动分成 wordLen 类情况
            for (int j = 0; j < wordLen; j++) {
                HashMap<String, Integer> hasWords = new HashMap<String, Integer>();
                int num = 0; //记录当前 HashMap2(这里的 hasWords 变量)中有多少个单词
                //每次移动一个单词长度
                for (int i = j; i < s.length() - wordNum * wordLen + 1; i = i + wordLen) {
                    boolean hasRemoved = false; //防止情况三移除后,情况一继续移除
                    while (num < wordNum) {
                        String word = s.substring(i + num * wordLen, i + (num + 1) * wordLen);
                        if (allWords.containsKey(word)) {
                            int value = hasWords.getOrDefault(word, 0);
                            hasWords.put(word, value + 1);
                            //出现情况三,遇到了符合的单词,但是次数超了
                            if (hasWords.get(word) > allWords.get(word)) {
                                // hasWords.put(word, value);
                                hasRemoved = true;
                                int removeNum = 0;
                                //一直移除单词,直到次数符合了
                                while (hasWords.get(word) > allWords.get(word)) {
                                    String firstWord = s.substring(i + removeNum * wordLen, i + (removeNum + 1) * wordLen);
                                    int v = hasWords.get(firstWord);
                                    hasWords.put(firstWord, v - 1);
                                    removeNum++;
                                }
                                num = num - removeNum + 1; //加 1 是因为我们把当前单词加入到了 HashMap 2 中
                                i = i + (removeNum - 1) * wordLen; //这里依旧是考虑到了最外层的 for 循环,看情况二的解释
                                break;
                            }
                            //出现情况二,遇到了不匹配的单词,直接将 i 移动到该单词的后边(但其实这里
                            //只是移动到了出现问题单词的地方,因为最外层有 for 循环, i 还会移动一个单词
                            //然后刚好就移动到了单词后边)
                        } else {
                            hasWords.clear();
                            i = i + num * wordLen;
                            num = 0;
                            break;
                        }
                        num++;
                    }
                    if (num == wordNum) {
                        res.add(i);
    
                    }
                    //出现情况一,子串完全匹配,我们将上一个子串的第一个单词从 HashMap2 中移除
                    if (num > 0 && !hasRemoved) {
                        String firstWord = s.substring(i, i + wordLen);
                        int v = hasWords.get(firstWord);
                        hasWords.put(firstWord, v - 1);
                        num = num - 1;
                    }
    
                }
    
            }
            return res;
        }
    }

    end

    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    leetcode----------Pascal's Triangle II
    leetcode----------Pascal's Triangle
    leetcode----------Climbing Stairs
    leetcode----------Balanced Binary Tree
    HTML的DOM树结构
    记一记流水账
    多校训练4——Hehe
    深啾啾~亚马逊与天猫大比拼
    Photo4
    第一次用FontLad~
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12164235.html
Copyright © 2020-2023  润新知