题目:给定一个字符串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;
}
}

Leetcode30--->Substring with Concatenation of All Words(主串中找出连接给定所有单词的子串的位置)的更多相关文章

  1. KMP小扩展,找出子串在主串中出现的所有位置

    KMP算法能够高效地匹配字符串,找出子串(T串)在主串(S串)中出现的首个位置的原算法网上已经有很多优秀的博文进行详细讲解,这里就不多赘述. 这篇博文主要是对KMP原算法稍作改动,使其能够在主串中把所 ...

  2. HDU 2087 剪花布条(模式串在主串中出现的次数主串中子串不可重叠)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 题意:求模式串在主串中出现的次数,与模式串匹配的子串之间不可重叠. 思路:用kmp算法解决,在匹 ...

  3. LeetCode30 Substring with Concatenation of All Words

    题目: You are given a string, s, and a list of words, words, that are all of the same length. Find all ...

  4. Substring with Concatenation of All Words, 返回字符串中包含字符串数组所有字符串元素连接而成的字串的位置

    问题描述:给定一个字符数组words,和字符串s,返回字符数组中所有字符元素组成的子串在字符串中的位置,要求所有的字符串数组里的元素只在字符串s中存在一次. 算法分析:这道题和strStr很类似.只不 ...

  5. POJ-3461 Oulipo(KMP,模式串在主串中出现次数)

    题意:给你两个字符串p和s,求出p在s中出现的次数. 显然,我们要先把模式串放到前面,之后主串放后面,中间隔开,这样就可以根据前缀数组的性质来求了. 我先想直接把p接到s前面,之后求Next数组对st ...

  6. maven主仓库中找不到restlet的解决办法

    解决办法: 修改Pom.xml  增加 <repositories>         <repository>             <id>maven-rest ...

  7. POJ 3461 Oulipo(模式串在主串中出现的次数)

    题目链接:http://poj.org/problem?id=3461 题意:给你两个字符串word和text,求出word在text中出现的次数 思路:kmp算法的简单应用,遍历一遍text字符串即 ...

  8. 【通过操作指针,与指针做函数參数&#39;实现字串在主串中出现的次数,然后将出现的部分依照要求进行替换 】

    #include<stdio.h> #include<stdlib.h> int strTime(const char *str1, const char *str2, int ...

  9. POJ 3461 Oulipo(模式串在主串中出现次数 可重叠)

    Oulipo [题目链接]Oulipo [题目类型]KMP &题意: 给你两个字符串p和s,求出p在s中出现的次数. &题解: kmpC函数就是解题的,其中也就j=nex[j]难理解一 ...

随机推荐

  1. java类及编写public类的基础点

    1.一个java文件中只能有一个public类.且公共类名称必须与java文件名一致,否则会出现错误提示.与其他面向对象编程语言的一样,在利用java分析问题时,基本思路即为将问题的属性(静)与行为( ...

  2. 【开发小结】Two Steps from Deadline

    进度条可以救我也可以杀死我 # START 2018年4月17日晚我测试了11组四则运算的UI,每个exe程序生成的每一道题都有恐怖的倒计时.PSP表格清晰的记录了开发过程中消耗的时间,但是在结对作业 ...

  3. UI设计中蕴涵着系统重要的数据结构与功能设计

    UI设计中蕴涵着系统重要的数据结构与功能设计 UI设计中的用户需求,事件(用例)驱动

  4. SQL Server 填充因子

    在创建聚集索引时,表中的数据按照索引列中的值的顺序存储在数据库的数据页中.在表中插入新的数据行或更改索引列中的值时,Microsoft®   SQL   Server™   2000   可能必须重新 ...

  5. 字符串(String)杂谈

    作者:臧圩人(zangweiren) 网址:http://zangweiren.javaeye.com >>>转载请注明出处!<<< 上一次我们已经一起回顾了面试题 ...

  6. Controller接收处理json、xml格式数据

    1.RequestBody接收json格式的数据,并直接转为对象. User.java使用lombok依赖包 @Data @AllArgsConstructor @NoArgsConstructor ...

  7. Write Once, Run Anywhere:这不是Java,这是C#

    注意,本文目的并非挑起语言之争.虽然有为C#平反之意,但主要还是介绍Mono并进行简单的测试. UPDATED: 25th August 2012 更新了「Compile Once, Run Anyw ...

  8. 2018.3.12 Leecode习题 给定一个整数数列,找出其中和为特定值的那两个数。

    给定一个整数数列,找出其中和为特定值的那两个数. 你可以假设每个输入都只会有一种答案,同样的元素不能被重用. 示例: 给定 nums = [2, 7, 11, 15], target = 9; 因为 ...

  9. Form组件的验证流程及扩展(钩子)

    Form组件的验证流程及扩展(钩子) 常用的form class TestForm(Form): t1 = fields.CharField( widget=widgets.Textarea # 输入 ...

  10. java基础—对象转型

    一.对象转型介绍 对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型.转型的意思是:如把float类型转成int类型,把double类 ...