LeetCode 0792. 匹配子序列的单词数
admin
2024-01-28 18:52:02
0

【LetMeFly】792.匹配子序列的单词数

力扣题目链接:https://leetcode.cn/problems/number-of-matching-subsequences/

给定字符串 s 和字符串数组 words, 返回  words[i] 中是s的子序列的单词个数 。

字符串的 子序列 是从原始字符串中生成的新字符串,可以从中删去一些字符(可以是none),而不改变其余字符的相对顺序。

  • 例如, “ace”“abcde” 的子序列。

 

示例 1:

输入: s = "abcde", words = ["a","bb","acd","ace"]
输出: 3
解释: 有三个是 s 的子序列的单词: "a", "acd", "ace"。

Example 2:

输入: s = "dsahjpjauf", words = ["ahjpjau","ja","ahbwzgqnuk","tnmlanowax"]
输出: 2

 

提示:

  • 1 <= s.length <= 5 * 104
  • 1 <= words.length <= 5000
  • 1 <= words[i].length <= 50
  • words[i]s 都只由小写字母组成。
​​​​

方法一:二分查找

方法一的思路是每个字符串单独处理。

首先需要预处理字符串s,记录下来s中每个字母的出现位置。 假如s = "aba",那么a出现的下标为[0, 2]b出现的下标为[1]

这样,在处理words中每个字符串的时候,只需要从前到后遍历字符串,在s中二分查找当前遍历到的字母即可。

  • 时间复杂度O(len(s)+N×len(s))O(len(s) + N\times len(s))O(len(s)+N×len(s)),其中NNN是wordswordswords中所有单词的个数
  • 空间复杂度O(len(s))O(len(s))O(len(s))

AC代码

C++

class Solution {
public:int numMatchingSubseq(string& s, vector& words) {vector a[26];for (int i = 0; i < s.size(); i++)a[s[i] - 'a'].push_back(i);int ans = 0;for (string& word : words) {bool ok = true;int loc = -1;for (char c : word) {vector::iterator it = lower_bound(a[c - 'a'].begin(), a[c - 'a'].end(), loc + 1);  // 在s中所有出现过字符c的下标中,找到大于loc的第一个下标if (it == a[c - 'a'].end()) {ok = false;break;}loc = *it;}ans += ok;}return ans;}
};

方法二:多指针

方法二的思路是遍历字符串s,在遍历的过程中,不断将这个字符对应的字符串的指针后移。

例如样例一:s = "abcde", words = ["a","bb","acd","ace"]

首先建立444个指针(因为有444个字符串)

a
↑bb
↑acd
↑ace
↑

然后建立一个大小为26的队列数组,队列中存放二十六个字母对应的指针

[0]: 0, 2, 3  // 是因为四个指针(0, 1, 2, 3)中,第0、2、3个指针所指的元素为a
[1]: 1  // 是因为四个指针中,第1号指针所指元素为b
[2]:
[3]:
[4]:
...
[25]:

接下来遍历字符串s

s的第一个字母为a,看a的队列,有三个指针0, 2, 3

将它们分别后移一位:

  • 0号指针对应字符串为a,指针后移一位达到了字符串的末尾,也就是说0号指针把字符串a“指完了”,因此as的子序列
  • 2号指针对应字符串为acd,指针后移一位,移动到c。因此队列[2]: 2
  • 3号指针对应字符串为ace,指针后移一位,移动到c。因此队列[2]: 3
[0]:
[1]: 1  // 是因为四个指针中,第1号指针所指元素为b
[2]: 2, 3
[3]:
[4]:
...
[25]:

s的第二个字母为b,看b的队列,有一个指针1

将它后移一位:

  • 1号指针对应字符串为bb,指针后移一位,移动到第二个b。因此队列[1]: 1
[0]:
[1]: 1
[2]: 2, 3
[3]:
[4]:
...
[25]:

s的第三个字母为c,看c的队列,有两个指针2, 3

将它们分别后移一位:

  • 2号指针对应字符串为acd,指针后移一位,移动到d。因此队列[3]: 2
  • 3号指针对应字符串为ace,指针后移一位,移动到e。因此队列[4]: 3
[0]:
[1]: 1
[2]:
[3]: 2
[4]: 3
...
[25]:

s的第四个字母为d,看d的队列,有一个指针2

将它后移一位:

  • 2号指针对应字符串为acd,指针后移一位达到了字符串的末尾,也就是说2号指针把字符串acd“指完了”,因此acds的子序列
[0]:
[1]: 1
[2]:
[3]:
[4]: 3
...
[25]:

s的第五个字母为e,看e的队列,有一个指针3

将它后移一位:

  • 3号指针对应字符串为ace,指针后移一位达到了字符串的末尾,也就是说3号指针把字符串ace“指完了”,因此aces的子序列
[0]:
[1]: 1
[2]:
[3]:
[4]:
...
[25]:

字符串s遍历结束,words中三个字符串是s的子序列

  • 时间复杂度O(len(s)+N)O(len(s) + N)O(len(s)+N),其中NNN是wordswordswords中所有单词的个数
  • 空间复杂度O(N+C)O(N + C)O(N+C),其中CCC是字符种类数小写字母个数262626

AC代码

C++

class Solution {
public:int numMatchingSubseq(string& s, vector& words) {queue q[26];  // q[0]: 下一个是'a'的word在words中的indexfor (int index = 0; index < words.size(); index++)q[words[index][0] - 'a'].push(index);vector loc(words.size(), 0);  // loc[0]: words[0]该匹配哪个单词了int ans = 0;for (char c : s) {for (int i = q[c - 'a'].size(); i > 0; i--) {int index = q[c - 'a'].front();q[c - 'a'].pop();loc[index]++;if (loc[index] == words[index].size()) {ans++;continue;}q[words[index][loc[index]] - 'a'].push(index);}}return ans;}
};

同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/127908867

上一篇:CNN网络结构-VGG

下一篇:JavaScript总结(一)

相关内容

热门资讯

明代的科举制度是怎样的? 明代的科举制度是怎样的?明代,生员参加每三年一次在省会举行的乡试,考中的称举人;举人参加每三年一次(...
婚后恋爱的言情小说 婚后恋爱的言情小说不懂说将来,艾米写得很好看。
要如何查有没有人偷我家的电? 要如何查有没有人偷我家的电?把自己家里的所有电器全部关闭,看看是否自己的电表是否还在运行,如果你的电...
用微笑掩饰,悲伤会没有吗? 用微笑掩饰,悲伤会没有吗?不会变,但是至少不会带给别人,你控制住了他的蔓延,当你知道自己没有让自己的...
后羿和杨戬哪个厉害,嫦娥更喜欢... 后羿和杨戬哪个厉害,嫦娥更喜欢谁,那些骗分的别回答你们说的都是废话,我不喜欢听废话嫦娥到底喜欢谁是她...
香辣土豆片的美味 在忙碌的生活中,我们总是渴望找到那些简单又美味的家常菜,既能满足味蕾,又能节省时间。今天,我要和大家...
原汁原味安徽菜!香菇鸡翅根,鲜... 安徽风味的香菇鸡翅根是一道家常又下饭的菜,鸡肉鲜嫩,香菇吸饱了汤汁,香味浓郁,吃起来特别入味。这道菜...
原创 晚... 一、夜晚饮食的特殊性 夜晚对于人体来说是一个特殊的时段,身体在经过一天的活动后,逐渐进入休息和修复的...
原创 老... 在乡村的怀抱中,美食不仅是味蕾的盛宴,更是心灵的慰藉。今天,我有幸为我的丈夫准备了一顿丰盛的晚餐,共...
8道早餐美食,让家人拥有好脾胃... 8道早餐美食,让家人拥有好脾胃口~ 一日之计在于晨,而早餐则是开启活力满满的一天的关键 “钥匙”;一...
原创 咖... 说到日本美食,很多人想到的是寿司、拉面、寿喜锅等食物。 但是如果你在日式料理店里,也能找到法式、意...
叶无心端木孤辰是哪部小说里的 叶无心端木孤辰是哪部小说里的《 穿越,第九个王妃 》,雪色水晶写的。
杨宗保死而复生是穆桂英挂帅第几... 杨宗保死而复生是穆桂英挂帅第几集38集死而复生
蒙太奇是什么意思?有哪些种类? 蒙太奇是什么意思?有哪些种类?RT蒙太奇(法语:Montage)是音译的外来语,原为建筑学术语,意为...
4月23日,是世界读书日,班里... 4月23日,是世界读书日,班里准备在 这天下午3点,在教室开展关于读书的主题班会。作为活动组织者,你...
中医里面,把药研细末炼蜜为丸,... 中医里面,把药研细末炼蜜为丸,是怎么炼蜜为丸了?。。。。先把药材磨成细粉,再把蜂蜜用小火煮,也就是炼...
新还珠格格晴儿的配音为什么和赵... 新还珠格格晴儿的配音为什么和赵丽颖本音那么像?今晚无聊打开看了看 怎么好像是她自己的声音 然后紫薇好...