ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[LeetCode] 792. Number of Matching Subsequences

2022-07-20 13:32:12  阅读:194  来源: 互联网

标签:遍历 word hashmap Number 单词 首字母 Subsequences words Matching


Given a string s and an array of strings words, return the number of words[i] that is a subsequence of s.

A subsequence of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters.

  • For example, "ace" is a subsequence of "abcde"

Example 1:

Input: s = "abcde", words = ["a","bb","acd","ace"]
Output: 3
Explanation: There are three strings in words that are a subsequence of s: "a", "acd", "ace".

Example 2:

Input: s = "dsahjpjauf", words = ["ahjpjau","ja","ahbwzgqnuk","tnmlanowax"]
Output: 2

Constraints:

  • 1 <= s.length <= 5 * 104
  • 1 <= words.length <= 5000
  • 1 <= words[i].length <= 50
  • s and words[i] consist of only lowercase English letters.

匹配子序列的单词数。

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/number-of-matching-subsequences
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路是桶排序。题意不难理解,给了一个字符串 s 和一串单词,请你计算有多少单词属于 s 的子序列。暴力解是把单词一个个拿出来看,用双指针的办法去跟 s 比较,看每个单词到底是不是 s 的子序列。这个做法可行,但是在 s 很长的情况下是会超时的。

一个相对优化的思路是桶排序。这里我们创建一个hashmap<Character, deque<String>>,key是26个字母,value是一个队列,队列里存的是所有首字母为 X 的单词。

首先第一轮初始化遍历 words 数组,把每个单词依据他们首字母的不同,放入 hashmap 的不同 key 下面。接着我们开始遍历字符串 s,每遇到一个字母 X,我们就去 hashmap 中拿出字母 X 背后对应的队列 queue。queue 中的单词都是首字母为 X 的单词。我们遍历这些单词,如果这时我们发现某个单词已经遍历完毕,说明这个单词就是 s 的子序列。对于没有遍历完的单词,去掉他的首字母,把 word.substring(1) 根据他当前新的首字母是什么,再放入hashmap中另外一个key背后的队列继续循环。

举例,比如题目中的第一个例子,我们创建了hashmap之后,开始遍历 s = "abcde"。一开始我们发现是字母 a,符合首字母为 a 的单词有 "a","acd","ace"。其中因为 "a" 已经遍历完毕,所以他就是满足题意的一个子序列。对于 "acd" 和 "ace" ,我们去掉他们的首字母,把 "cd" 和 "ce" 加入 hashmap 中 key 为 "c" 的那个队列继续参与遍历。

此时我们遍历到了字母 b,s = "abcde"。因为 hashmap 中没有首字母是 b 的单词所以直接看下一个字母。此时我们遍历到了字母 c,s = "abcde"。此时 "cd" 和 "ce" 都满足首字母为 "c",我们再把这两个单词分别去掉他们的首字母,再放回 hashmap 中 key 为 "d" 和 "e" 的队列。依据这个思路,最后 "cd" 和 "ce" 也都会被遇到,所以最后答案是有 3 个单词是 s 的子序列。

时间O(n^2) - worst case,所有单词都是 s 的子序列且所有单词都跟 s 一样长

空间O(n) - hashmap

Java实现

 1 class Solution {
 2     public int numMatchingSubseq(String s, String[] words) {
 3         HashMap<Character, Deque<String>> map = new HashMap<>();
 4         for (char c = 'a'; c <= 'z'; c++) {
 5             map.put(c, new ArrayDeque<>());
 6         }
 7         // 把所有的单词按照首字母不同放入hashmap
 8         for (String word : words) {
 9             map.get(word.charAt(0)).offer(word);
10         }
11 
12         int count = 0;
13         for (char c : s.toCharArray()) {
14             Deque<String> queue = map.get(c);
15             int size = queue.size();
16             for (int i = 0; i < size; i++) {
17                 String word = queue.poll();
18                 if (word.length() == 1) {
19                     count++;
20                 } else {
21                     map.get(word.charAt(1)).offer(word.substring(1));
22                 }
23             }
24         }
25         return count;
26     }
27 }

 

LeetCode 题目总结

标签:遍历,word,hashmap,Number,单词,首字母,Subsequences,words,Matching
来源: https://www.cnblogs.com/cnoodle/p/16497623.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有