zoukankan      html  css  js  c++  java
  • Leetcode30--->Substring with Concatenation of All Words(主串中找出连接给定所有单词的子串的位置)

    题目:给定一个字符串S(主串),一个字符串数组words,其中的字符串的长度相同。找到所有的子串位置,要求是words中字符串的一个连接;

    举例:

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

    You should return the indices: [0,9].

    解题思路:

    1. 采用窗口机制,假设此时每个单词的长度为wordlen;

    2.   先将words中的单词存储在hashmap中,key为单词,value为单词出现的次数;

    3. 在S中以单词长遍历每个单词,看其在hashmap中是否出现,若出现,则窗口的左边界即可确定,然后依次向后遍历,若其中有单词不出现在hashmap中,则直接看下一个单词,窗口的左边界也会更新。若从窗口的左边界遍历找到了与words中单词相拼接的字符串,则将左窗口位置加入到结果集中,左窗口移向下一个单词。

    代码如下:

     1 public class Solution {
     2     public List<Integer> findSubstring(String s, String[] words) {
     3         List<Integer> list = new ArrayList<Integer>();
     4         if(s == null || words == null || s.length() < 1 || words.length < 1)
     5             return list;
     6         HashMap<String, Integer> hm = new HashMap<String, Integer>();
     7         for(int i = 0, len = words.length; i < len; i++)   // 将数组中的单词放入到hashmap中,由于数组中有可能有多个相同的单词,所以还需要计数
     8         {
     9             if(hm.containsKey(words[i]))
    10                 hm.put(words[i], hm.get(words[i]) + 1);
    11             else
    12                 hm.put(words[i], 1);
    13         }
    14         int wordlen = words[0].length(); // 单词的长度
    15         int strlen = words.length; // 单词所组成串的长度
    16         int i = 0; // 循环的次数
    17         int len = s.length();
    18         while(i < wordlen)
    19         {
    20             int left = i; // 窗口的左边界
    21             int count = 0; // 匹配了hm中的单词数目
    22             HashMap<String, Integer> curr = new HashMap<String, Integer>(); // 记录窗口中已经匹配的单词及其出现的次数
    23             for(int j = i; j <= len - wordlen; j = j + wordlen)
    24             {
    25                 String str = s.substring(j, j + wordlen);  // 取一个单词
    26                 if(hm.containsKey(str))  // 如果字典中包含该单词
    27                 {
    28                     if(curr.containsKey(str))  // 将单词加入到当前遍历的字典中
    29                         curr.put(str, curr.get(str) + 1);
    30                     else
    31                         curr.put(str, 1);
    32                     if(hm.get(str) >= curr.get(str))  // str在主串中出现的次数不能小于当前窗口的str出现的次数,否则窗口就要缩小
    33                         count ++;
    34                     else
    35                     {
    36                         while(hm.get(str) < curr.get(str))  // 如果当前窗口的单词出现次数大于给定的数组中的单词次数,窗口需要缩小
    37                         {
    38                             String temp = s.substring(left, left + wordlen);
    39                             if(curr.containsKey(temp))
    40                             {
    41                                  curr.put(temp, curr.get(temp) - 1);
    42                                  if(curr.get(temp) < hm.get(temp))
    43                                     count--;
    44                             }
    45                            left += wordlen;
    46                         }
    47                     }
    48                     if(count == strlen)  // 如果此时curr中所保存的单词数量与给定的words中的单词数目是一样的,则将当前窗口的左边缘加入结果
    49                     {
    50                         list.add(left);
    51                         String ss = s.substring(left, left + wordlen);
    52                         if(curr.containsKey(ss))
    53                         {
    54                             curr.put(ss, curr.get(ss) - 1);
    55                             count -- ;
    56                         }
    57                         left += wordlen;
    58                     }
    59                 }
    60                 else  // 如果字典中不包含该单词,则直接看下一个单词
    61                 {
    62                     left =  j + wordlen;
    63                     count  = 0;
    64                     curr.clear();
    65                 }
    66             }
    67             i ++;
    68         }
    69         return list;
    70     }
    71 }
  • 相关阅读:
    洛谷P1071 潜伏者
    2019BJFU 网站设计(孙俏-web前端开发)实验代码-181002222
    反思——P1307 数字反转
    洛谷P1067 多项式输出
    湖南大学第十五届程序设计竞赛(重现赛)
    2019河北省大学生程序设计竞赛(重现赛)
    2019BJFU C++实验习题(完结)
    配置android source 在ubuntu中编译环境
    Android屏幕保持唤醒状态
    Android richtext
  • 原文地址:https://www.cnblogs.com/leavescy/p/5895692.html
Copyright © 2011-2022 走看看