zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    
  • 相关阅读:
    xuexi
    太厉害了!腾讯T4大牛把《数据结构与算法》讲透了,带源码笔记
    python 死循环
    redis 锁
    Opencv4.1.0交叉编译----终端摄像头内算法嵌入,海思HISI、雄迈ARM编译链使用经验
    SpringCloud之FeignClient调用跨微服接口
    Elasticsearch父子级查询及祖孙辈parent/child关联查询
    服务器ip地址与域名解析及http转https
    RestTemplate请求第三方接口添加Headers token及设置请求体
    kanzi 一些基础参数变量
  • 原文地址:https://www.cnblogs.com/mapoos/p/13186614.html
Copyright © 2011-2022 走看看