LeetCode 30 Substring with Concatenation of All Words

2024-09-05 03:08

本文主要是介绍LeetCode 30 Substring with Concatenation of All Words,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意:

给出字符串s和许多等长(len)单词w,找出所有s中的满足子串为w中所有单词的一种组合的位置。


思路:

因为w中的单词要满足的是组合而不是排列,因此用“区间[L,R]中包含单词的计数”来维护比较合适。

一是满足了组合对顺序的不要求,二是方便处理重复的单词。

首先可以统计一下,w中各种单词个数。如果s的长度为size(w) * len的子串单词计数与w相同,则找到一个答案。

接着去s中找到所有w中单词出现的位置,因为单词等长,所以可以开一个长度为size(s)的数组A,A[i]记录着从i位置开始长度为len的s的子串对应哪个单词。

然后枚举区间[L,R]判断是否为答案。可以这样做,L起始位置枚举[0, len - 1],初始R与L相同表示空队列,接着R端每次入队一个len长度的s的子串,如果队列长度超过size(w) * len则队首出队,再检查队列中字符串的计数,如果与w相同,则记录答案。这里还有一个维护技巧,为了避免对应单词的计数的比较,可以维护队列中单词的计数一定小于w中计数,方法就是一旦队列中某单词x计数多了,那么L不断右移len个单位,直到x计数满足条件为止。

最后将答案返回。


代码:

class Solution {
public:vector<int> findSubstring(string s, vector <string> &words) {vector<int> ans;ans.clear();if (words.size() == 0) {return ans;}map<string, int> hash;hash.clear();for (int i = 0, idx = 0; i < words.size(); ++i) {if (!hash.count(words[i])) {hash[words[i]] = idx++;}}int *cnt = new int[hash.size()];memset(cnt, 0, sizeof(int) * hash.size());for (int i = 0, idx = 0; i < words.size(); ++i) {++cnt[hash[words[i]]];}int *start = new int[s.size()];memset(start, -1, sizeof(int) * s.size());for (auto i = hash.begin(); i != hash.end(); ++i) {for (int idx = -1; idx + 1 < s.size();) {idx = s.find(i->first, idx + 1);if (idx != -1) {start[idx] = i->second;} else {break;}}}int len = words[0].size();for (int i = 0; i < len; ++i) {int tmpcnt = 0;int k = i;for (int j = i; j + len <= s.size(); j += len) {if ((j - k) / len == words.size()) {if (start[k] != -1) {--tmpcnt;++cnt[start[k]];}k += len;}if (start[j] != -1) {--cnt[start[j]];++tmpcnt;while (cnt[start[j]] < 0) {if (start[k] != -1) {--tmpcnt;++cnt[start[k]];}k += len;}if (tmpcnt == words.size()) {ans.push_back(j - (tmpcnt - 1) * len);}}}for (; k + len <= s.size(); k += len) {if (start[k] != -1) {++cnt[start[k]];}}}sort(ans.begin(), ans.end());return ans;}
};


这篇关于LeetCode 30 Substring with Concatenation of All Words的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1137797

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

30常用 Maven 命令

Maven 是一个强大的项目管理和构建工具,它广泛用于 Java 项目的依赖管理、构建流程和插件集成。Maven 的命令行工具提供了大量的命令来帮助开发人员管理项目的生命周期、依赖和插件。以下是 常用 Maven 命令的使用场景及其详细解释。 1. mvn clean 使用场景:清理项目的生成目录,通常用于删除项目中自动生成的文件(如 target/ 目录)。共性规律:清理操作

2024网安周今日开幕,亚信安全亮相30城

2024年国家网络安全宣传周今天在广州拉开帷幕。今年网安周继续以“网络安全为人民,网络安全靠人民”为主题。2024年国家网络安全宣传周涵盖了1场开幕式、1场高峰论坛、5个重要活动、15场分论坛/座谈会/闭门会、6个主题日活动和网络安全“六进”活动。亚信安全出席2024年国家网络安全宣传周开幕式和主论坛,并将通过线下宣讲、创意科普、成果展示等多种形式,让广大民众看得懂、记得住安全知识,同时还

HDUPlay on Words

1.定理:无向图G有欧拉通路的充分必要条件是G为连通图,并且G仅有两个奇度结点或者无奇度结点。 (1)当G是仅有两个奇度结点的连通图时,G的欧拉通路必以此两个结点为端点。 (2)当G是无奇度结点的连通图时,G必有欧拉回路。 2.一个有向图D具有欧拉通路,当且仅当D是连通的,且除了两个顶点外,其余顶点的入度均等于出度,这两个特殊的顶点中,一个顶点的入度比出度大1,另一个顶点的入度比出度小1

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param