题目:给定一个字符串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中单词相拼接的字符串,则将左窗口位置加入到结果集中,左窗口移向下一个单词。

代码如下:

 public class Solution {
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> list = new ArrayList<Integer>();
if(s == null || words == null || s.length() < 1 || words.length < 1)
return list;
HashMap<String, Integer> hm = new HashMap<String, Integer>();
for(int i = 0, len = words.length; i < len; i++) // 将数组中的单词放入到hashmap中,由于数组中有可能有多个相同的单词,所以还需要计数
{
if(hm.containsKey(words[i]))
hm.put(words[i], hm.get(words[i]) + 1);
else
hm.put(words[i], 1);
}
int wordlen = words[0].length(); // 单词的长度
int strlen = words.length; // 单词所组成串的长度
int i = 0; // 循环的次数
int len = s.length();
while(i < wordlen)
{
int left = i; // 窗口的左边界
int count = 0; // 匹配了hm中的单词数目
HashMap<String, Integer> curr = new HashMap<String, Integer>(); // 记录窗口中已经匹配的单词及其出现的次数
for(int j = i; j <= len - wordlen; j = j + wordlen)
{
String str = s.substring(j, j + wordlen); // 取一个单词
if(hm.containsKey(str)) // 如果字典中包含该单词
{
if(curr.containsKey(str)) // 将单词加入到当前遍历的字典中
curr.put(str, curr.get(str) + 1);
else
curr.put(str, 1);
if(hm.get(str) >= curr.get(str)) // str在主串中出现的次数不能小于当前窗口的str出现的次数,否则窗口就要缩小
count ++;
else
{
while(hm.get(str) < curr.get(str)) // 如果当前窗口的单词出现次数大于给定的数组中的单词次数,窗口需要缩小
{
String temp = s.substring(left, left + wordlen);
if(curr.containsKey(temp))
{
curr.put(temp, curr.get(temp) - 1);
if(curr.get(temp) < hm.get(temp))
count--;
}
left += wordlen;
}
}
if(count == strlen) // 如果此时curr中所保存的单词数量与给定的words中的单词数目是一样的,则将当前窗口的左边缘加入结果
{
list.add(left);
String ss = s.substring(left, left + wordlen);
if(curr.containsKey(ss))
{
curr.put(ss, curr.get(ss) - 1);
count -- ;
}
left += wordlen;
}
}
else // 如果字典中不包含该单词,则直接看下一个单词
{
left = j + wordlen;
count = 0;
curr.clear();
}
}
i ++;
}
return list;
}
}

最新文章

  1. Android基础总结(三)
  2. .NET LINQ 数据分区
  3. 定时器的fireDate指的是触发时间
  4. Linked List Cycle II || LeetCode
  5. Cocos2d中使用颜色混合:加算,减算
  6. openGL 提升渲染性能 之 顶点数组 VBO IBO VAO
  7. 关于cookie
  8. js ||与&amp;&amp;
  9. Linux系统监控
  10. Microsoft.Jet.OLEDB.4.0和Microsoft.ACE.OLEDB.12.0的适用版本
  11. jquery获取文件名称
  12. [iOS]从零开始开发一个即时通讯APP
  13. 用最简单的方法判断JavaScript中this的指向
  14. 解决Oracle登录时出现无法处理服务名问题
  15. 初识java——运算符和表达式以及注释
  16. GraphQL ---02 GraphQL和C#结合的实战项目
  17. anaconda3安装cv2模块(python3.6)
  18. 7-27 Codeforces Round #499 (Div. 2)
  19. [Draft]iOS.ObjC.Pattern.Builder-Pattern
  20. python列表操作方法

热门文章

  1. tomcat配置https 和 http强制跳转https
  2. HTML 中的特殊字符
  3. Page_Load与sender -- PostBack是由哪个 ASP.NET控件引起 ?
  4. UVA1607 Gates 与非门电路 (二分)
  5. [论文理解]Selective Search for Object Recognition
  6. Controller接收处理json、xml格式数据
  7. Ajax获取服务器响应头部信息
  8. 在ProgressBar控件中显示进度百分比
  9. Google 出品的 Java 编码规范,强烈推荐,权威又科学!
  10. Git基本操作笔记:初始化,用户设置,撤销修改