zoukankan      html  css  js  c++  java
  • LeetCode 30. Substring with Concatenation of All Words

    原题链接在这里: https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/

    题目: 

    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.

    For example, given:
    s: "barfoothefoobarman"
    words: ["foo", "bar"]

    You should return the indices: [0,9].
    (order does not matter).

    题解:

    类似Longest Substring Without Repeating Characters, 这类快慢指针维护substring的方法在Minimum Window Substring里有总结.

    需要先生成global map计算words中每个word 的frequency. 快慢指针围成的window里也有个小的map计算map中出现在words的word, 当出现一个就count++.

    当count是words数目和时就找到了一个结果.

    检查当前词是否是words里的词时外层循环是多种取词方法,以例子来说就是分成:

    |bar|foo|the|foo|bar|man

    b|arf|oot|hef|oob|arm|an

    ba|rfo|oth|efo|oba|rma|n

    Note: s.substring(startIndex, endIndex) 其中的endIndex必须比s string本身长度小.

    Time Complexity: O(s.length()).

    Space: O(words.length). 

    AC Java:

     1 class Solution {
     2     public List<Integer> findSubstring(String s, String[] words) {
     3         List<Integer> res = new ArrayList<Integer>();
     4         if(words == null || words.length == 0 || s == null || s.length() == 0){
     5             return res;
     6         }
     7         
     8         // 计算原有word frequency
     9         HashMap<String, Integer> hm = new HashMap<String, Integer>();
    10         for(String word : words){
    11             hm.put(word, hm.getOrDefault(word, 0)+1);
    12         }
    13         
    14         int wordLen = words[0].length();
    15         int count = 0;
    16         int walker = 0;
    17         
    18         // 从等长word长度的开始到结尾挨个试,不需要再往后,因为那已经被长度开始里面的runner下一跳包括
    19         for(int i = 0; i<wordLen; i++){
    20             walker = i;
    21             count = 0;
    22             HashMap<String, Integer> windowHm = new HashMap<String, Integer>();
    23             int max = s.length()-wordLen+1;
    24             
    25             for(int runner = walker; runner < max; runner += wordLen){
    26                 String cur = s.substring(runner, runner+wordLen);
    27                 if(hm.containsKey(cur)){
    28                     // cur string在words中
    29                     windowHm.put(cur, windowHm.getOrDefault(cur, 0)+1);
    30                     if(windowHm.get(cur) <= hm.get(cur)){
    31                         count++;
    32                     }else{
    33                         // cur这个词在window里出现的次数 多余 原来words中的次数
    34                         while(windowHm.get(cur) > hm.get(cur)){
    35                             String walkerStr = s.substring(walker, walker+wordLen);
    36                             windowHm.put(walkerStr, windowHm.get(walkerStr)-1);
    37                             if(windowHm.get(walkerStr) < hm.get(walkerStr)){
    38                                 count--;
    39                             }
    40                             walker += wordLen;
    41                         }
    42                     }
    43                     
    44                     // 全部覆盖,向前移动walker
    45                     if(count == words.length){
    46                         res.add(walker);
    47                         String walkerStr = s.substring(walker, walker+wordLen);
    48                         windowHm.put(walkerStr, windowHm.get(walkerStr)-1);
    49                         count--;
    50                         walker += wordLen;
    51                     }
    52                 }else{
    53                     // cur 不在words中
    54                     windowHm.clear();
    55                     count = 0;
    56                     walker = runner+wordLen;
    57                 }
    58             }
    59         }
    60         
    61         return res;
    62     }
    63 }
  • 相关阅读:
    2017-5-15 winform项目总结(知识点补充)
    2017-5-7 time控件 三级联动(省,市,区)
    2017-5-4 进程 线程 用户控件
    2017-5-3 打印控件 MDI 窗体容器 Activated事件
    2017-5-2 对话框控件 MessageBox.Show()用法补充 打开新窗体的3中模式
    窗体移动 窗体阴影API
    2017-4-28 ListView控件学习
    【2017-03-28】JS基础、DOM操作
    【2017-03-24】样式表样式
    【2017-03-24】CSS样式表
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4825046.html
Copyright © 2011-2022 走看看