代码重构:leetcode 30. 串联所有单词的子串

228 阅读1分钟

30. 串联所有单词的子串

如果我们把单词看成一个整体,就变成了类似【字符串中找最长不重复的字符子串】,为了能使得我们得到完整的遍历空间。

假设数组长度*单词长度=k,要遍历所有可能,需要[0~n-k]单词作为起点来判断是否可能。

实际上我们需要考虑的是没我们以单词长度为单位来移动,分别以第一个单词的每个字符作为起点,就可以找到等价上面的所有所有的可能性。

于是就可以进行具体建模:

定义left和right,并保证[left,right)区间内的都处于合法状态(每一单词在单词数组里面,且数量不超过),只要这样延伸到满足每一单词都数量相等,即为答案。

找到答案后,需再找答案空间,就是将left右移一个单位。

    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> ans = new ArrayList<>();
        if (words == null || words.length == 0) return ans;
        HashMap<String, Integer> set = new HashMap<>();
        for (String i : words) set.put(i, set.getOrDefault(i, 0) + 1);
        int len = words[0].length();
        for (int i = 0; i < len; i++) {
            HashMap<String, Integer> judge = new HashMap<>();
            int left = i, right = i;
            for (; right <= s.length() - len; right += len) {
                String t = s.substring(right, right + len);
                if (!set.containsKey(t)) {
                    for (; left < right; left += len) {
                        String tt = s.substring(left, left + len);
                        judge.put(tt, judge.getOrDefault(tt, 1) - 1);
                    }
                    left += len;
                    continue;
                }
                else if (judge.getOrDefault(t,0)>=set.get(t)){
                    for (; judge.get(t)>=set.get(t); left += len) {
                        String tt = s.substring(left, left + len);
                        judge.put(tt, judge.getOrDefault(tt, 1) - 1);
                    }
                }
                if (set.containsKey(t)) judge.put(t, judge.getOrDefault(t, 0) + 1);
                if (set.size() == judge.size()) {
                    boolean isChecked = true;
                    for (Map.Entry<String, Integer> entry : set.entrySet()) {
                        if (!judge.getOrDefault(entry.getKey(), 0).equals(entry.getValue())) {
                            isChecked = false;
                            break;
                        }
                    }
                    if (isChecked) {
                        ans.add(left);
                        String tt = s.substring(left, left + len);
                        judge.put(tt, judge.getOrDefault(tt, 1) - 1);
                        left += len;
                    }
                }
            }
        }
        return ans;
    }