小鱼刷leetcode---792. 匹配子序列的单词数

120 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第27天,点击查看活动详情

一 描述

792. 匹配子序列的单词数 - 力扣(LeetCode)

给定字符串 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 * 10^4
  • 1 <= words.length <= 5000
  • 1 <= words[i].length <= 50
  • words[i]和 s 都只由小写字母组成。

二 分析

字典树构建完成后,深度优选遍历字典树

判断结点所代表的字符,是否出现在后续字符串中

以测试用例:"abcde",["a","bb","acd","ace"]为例:

首次进入方法时,结点为root,字符串的起始位置为0

root结点的e为0,不加入结果

root的后续结点有a、b两个结点

a在字符串中存在,且下标为0。

递归调用search方法,结点为a,字符串的起始位置为1(0+1)

a结点的e为1,将1加入结果

a的后续结点有c结点

此时判断c在字符串中是否存在时,需要从a的后面开始查找,

这就是传入的起始位置的作用

三 答案

class Solution {
        public int numMatchingSubseq(String s, String[] words) {
            Trie trie = new Trie();
            for (String word : words) {
                trie.insert(word);
            }
            return trie.search(s);
        }

        class Node {
            int e;
            Node[] nexts = new Node[26];
        }

        class Trie {
            Node root;

            public Trie() {
                root = new Node();
            }

            public void insert(String word) {
                Node cur = root;
                int index;
                for (char c : word.toCharArray()) {
                    index = c - 'a';
                    if (cur.nexts[index] == null) {
                        cur.nexts[index] = new Node();
                    }
                    cur = cur.nexts[index];
                }
                cur.e++;

            }

            int result;

            public int search(String word) {
                search(word, 0, root);
                return result;
            }

           
            public void search(String word, int index, Node node) {
                if (node.e > 0) {
                    result += node.e;
                }
                Node next;
                int indexOf;
                for (int i = 0; i < node.nexts.length; i++) {
                    next = node.nexts[i];
                    if (next != null) {
                        indexOf = word.indexOf(i + 'a', index);
                        if (indexOf != -1) {
                            search(word, indexOf + 1, next);
                        }
                    }
                }
            }
        }
    }

四 参考

桶子,要从题目细节入手 - 匹配子序列的单词数 - 力扣(LeetCode)