leetcode的串联所有单词的子串

简介: leetcode的串联所有单词的子串

公众号merlinsea


题目描述


   给定一个字符串 s 和一些 长度相同 的单词 words 。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。

链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words


示例


输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。


解题思路:

   双hashMap+滑动窗口实现。这种题目特点就是条件要求全部满足的连续子序列, 如果出现了条件不满足的情况就应该停下来通过移动左边界直至条件满足才能继续向下 执行。


代码实现:


class Solution {
    private Map<String,Integer> map = new HashMap<>();
    public List<Integer> findSubstring(String s, String[] words) {
        ArrayList<Integer> list = new ArrayList<>();
        int oneWordLen = words[0].length();
        for(String word : words){
            map.put(word,map.getOrDefault(word,0)+1);
        }
        for(int i = 0;i<oneWordLen;i++){
            int left = i;
            int right = i;
            int count = 0;
            Map<String,Integer> tempMap = new HashMap<>();
            while(right+oneWordLen<=s.length()){
                String word = s.substring(right,right+oneWordLen);
                right = right+oneWordLen;
                if(!map.containsKey(word)){
                    //当前word不在map中,那么不论怎么移动left都无济于事
                    count=0;
                    tempMap.clear();
                    left=right;
                }else{
                    count++;
                    tempMap.put(word,tempMap.getOrDefault(word,0)+1);
                    while(tempMap.get(word) > map.get(word)){
                        //出现了条件不满足的情况应该停下来移动左边界直到条件满足为止
                        String firstWord = s.substring(left,left+oneWordLen);
                        left = left+oneWordLen;
                        tempMap.put(firstWord,tempMap.get(firstWord)-1);
                        count--;
                    }
                    if(count==words.length){
                        list.add(left);
                        count--;
                        String firstWord = s.substring(left,left+oneWordLen);
                        left=left+oneWordLen;
                        tempMap.put(firstWord,tempMap.get(firstWord)-1);
                    }
                }
            }
        }
        return list;
    }
}
相关文章
|
2月前
Leetcode(最后一个单词长度)
这篇文章介绍了两种解决LeetCode第58题的方法,即计算给定字符串中最后一个单词的长度,方法包括翻转字符串和逆向遍历统计。
22 0
|
2月前
【LeetCode 20】151.反转字符串里的单词
【LeetCode 20】151.反转字符串里的单词
21 0
|
4月前
|
算法
LeetCode第58题最后一个单词的长度
LeetCode第58题"最后一个单词的长度"的解题方法,通过从字符串末尾向前遍历并计数非空格字符,直接得出最后一个单词的长度。
LeetCode第58题最后一个单词的长度
|
4月前
|
算法 JavaScript Python
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
53 4
|
4月前
|
Python
【Leetcode刷题Python】生词本单词整理
文章提供了一个Python程序,用于帮助用户整理和排版生词本上的单词,包括去除重复单词、按字典序排序,并按照特定的格式要求进行打印排版。
47 3
|
4月前
|
Python
【Leetcode刷题Python】318. 最大单词长度乘积
本文提供了LeetCode题目318的Python编程解决方案,题目要求在一个字符串数组中找出两个不含有公共字母的单词,且这两个单词的长度乘积最大,如果不存在这样的两个单词,则返回0。
22 0
|
6月前
|
存储 算法 测试技术
力扣经典150题第三十三题:最小覆盖子串
力扣经典150题第三十三题:最小覆盖子串
56 1
|
6月前
|
算法 测试技术 索引
力扣经典150题第三十二题:串联所有单词的子串
力扣经典150题第三十二题:串联所有单词的子串
30 0
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
125 2