• 0030. Substring with Concatenation of All Words (H)


    Substring with Concatenation of All Words (H)

    题目

    You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

    Example 1:

    Input:
      s = "barfoothefoobarman",
      words = ["foo","bar"]
    Output: [0,9]
    Explanation: Substrings starting at index 0 and 9 are "barfoo" and "foobar" respectively.
    The output order does not matter, returning [9,0] is fine too.
    

    Example 2:

    Input:
      s = "wordgoodgoodgoodbestword",
      words = ["word","good","best","word"]
    Output: []
    

    题意

    给定一个字符串s和单词数组words,判断s中是否存在一个子串,正好为words中所有单词连起来的字符串(顺序不计)。

    思路

    暴力法:直接将每个单词看做是一个字符进行匹配,因为单词的顺序不一定,可以用HashMap来记录单词和出现次数的对应关系。

    (O(N))优化:暴力法的缺陷在于进行了大量的重复计算。参考 LeetCode 30. Substring with Concatenation of All Words 进行优化。


    代码实现

    Java

    暴力

    class Solution {
        public List<Integer> findSubstring(String s, String[] words) {
            if (words.length == 0) {
                return new ArrayList<>();
            }
          
            int len = words[0].length(), num = words.length;
            List<Integer> list = new ArrayList<>();
            Map<String, Integer> record = new HashMap<>();
            Map<String, Integer> tmp = new HashMap<>();
          
            for (String word : words) {
                record.putIfAbsent(word, 0);
                record.put(word, record.get(word) + 1);
            }
          
            for (int i = 0; i < s.length(); i++) {
                if (s.length() - i < num * len) {
                    break;
                }
              
    						tmp.clear();
                int j = i;
              
                while (j - i != num * len) {
                    String w = s.substring(j, j + len);
                    if (!record.containsKey(w)) {
                        break;
                    }
                    tmp.putIfAbsent(w, 0);
                    tmp.put(w, tmp.get(w) + 1);
                    if (tmp.get(w) > record.get(w)) {
                        break;
                    }
                    j += len;
                }
              
                if (j - i == num * len) {
                    list.add(i);
                }
            }
            return list;
        }
    }
    

    (O(N))优化

    class Solution {
        public List<Integer> findSubstring(String s, String[] words) {
            if (words.length == 0) {
                return new ArrayList<>();
            }
          
            int len = words[0].length(), num = words.length;
            List<Integer> list = new ArrayList<>();
            Map<String, Integer> record = new HashMap<>();
            Map<String, Integer> tmp = new HashMap<>();
          
            for (String word : words) {
                record.putIfAbsent(word, 0);
                record.put(word, record.get(word) + 1);
            }
    
            for (int i = 0; i < len && i < s.length(); i++) {
                if (s.length() - i < num * len) {
                    break;
                }
              
                tmp.clear();
                int left = i, right = i;
              
                while (true) {
                    if (right - left == num * len) {
                        list.add(left);
                        String headW = s.substring(left, left + len);
                        tmp.put(headW, record.get(headW) - 1);
                        left += len;
                    }
                  
                    if (s.length() - left < num * len) {
                        break;
                    }
                  
                    String w = s.substring(right, right + len);
                  
                    if (!record.containsKey(w)) {
                        tmp.clear();
                        left = right + len;
                    } else {
                        tmp.putIfAbsent(w, 0);
                        tmp.put(w, tmp.get(w) + 1);
                        while (tmp.get(w) > record.get(w) && s.length() - left >= num * len) {
                            String headW = s.substring(left, left + len);
                            tmp.put(headW, tmp.get(headW) - 1);
                            left += len;
                        }
                    }
                  
                    right += len;
                }
            }
    
            return list;
        }
    }
    
  • 相关阅读:
    浙江省CIO协会钱塘江论坛近日在网易云创沙龙宣布成立
    用Python解析XMind
    Flask写web时cookie的处理
    一篇文章看懂Facebook和新浪微博的智能FEED
    改进网易云音乐的“音乐社交”构想
    移动端爬虫工具与方法介绍
    用供应链管理思路降低教培产品成本
    【网易严选】iOS持续集成打包(Jenkins+fastlane+nginx)
    网易严选的wkwebview测试之路
    linux多进程之间的文件锁
  • 原文地址:https://www.cnblogs.com/mapoos/p/13186614.html
Copyright © 2020-2023  润新知