首页 > 其他分享 >LeetCode -- 792. 匹配子序列的单词数

LeetCode -- 792. 匹配子序列的单词数

时间:2023-07-08 16:46:18浏览次数:38  
标签:792 -- res ++ int words auto LeetCode size

 方法1:利用桶的思想同时匹配所有words中的子串 (走路写法)

把所有首字母相同的子串放入到一个桶中,然后遍历s,对于首字母为s[i]的单词,若其大小为1则res ++, 否则删掉s[i],并根据s[i + 1]放入新的桶中。

c ++ 
class Solution {
public:
    int numMatchingSubseq(string s, vector<string>& words) {
        vector<queue<string>> d(26);
        for(auto &w : words) {
            d[w[0] - 'a'].push(w);
        }

        int res = 0;
        for(auto &c : s) {
            auto &q = d[c - 'a'];
            for(int i = q.size(); i; i -- ) {
                auto t = q.front();
                q.pop();
                if(t.size() == 1) res ++ ;
                else d[t[1] - 'a'].push(t.substr(1));
            }
        }
        return res;
    }
};

方法二 :地址哈希与二分查找  (自行车写法)

我们把每个字母的下标进行映射,pos[0] 及所有 'a'字符在s中的下标,并这些下标有小到大排序。

对于每个word子串,用upper_bound()遍历其每个字符的位置,当有字符的位置为pos[i].end()时,表示不存在,及word不是s的子串。

c ++ 
class Solution {
public:
    int numMatchingSubseq(string s, vector<string>& words) {
        vector<vector<int>> pos(26);

        for(int i = 0; i < s.size(); i ++ ) {
            pos[s[i] - 'a'].push_back(i);
        }

        int res = words.size();
        for(auto &word : words) {
            if(word.size() > s.size()) {
                res -- ;
                continue;
            }

            int p = -1;
            for(auto c : word) {
                auto &ps = pos[c - 'a'];
                auto it = upper_bound(ps.begin(), ps.end(), p);
                if(it == ps.end()) {
                    res -- ;
                    break;
                }
                p = *it;
            }
        }
        return res;

    }
};

方法三:桶 + 多指针   (摩托车写法)

我们对每个子串记录一个类似文件指针的字符指针,该指针指向了当前遍历到了子串的什么位置

当字符指针的值为word.size()时,res ++ ;否则将该字符串加入对应的桶中

c ++ 
class Solution {
public:
    int numMatchingSubseq(string s, vector<string>& words) {
        vector<queue<pair<int, int>>> queues(26);
        for(int i = 0; i < words.size(); i ++ ) {
            queues[words[i][0] - 'a'].push({i, 0});
        }

        int res = 0;
        for(auto c : s) {
            auto &q = queues[c - 'a'];
            int sz = q.size();
            while(sz -- ) {
                auto [i, j] = q.front();
                q.pop();
                j ++ ;
                if(j == words[i].size()) {
                    res ++ ;
                } else {
                    queues[words[i][j] - 'a'].push({i, j});
                }
            }
        }

        return res;
    }
};
java
class Solution {
    public int numMatchingSubseq(String s, String[] words) {
        Queue<int[]>[] p = new Queue[26];
        for(int i = 0; i < 26; i ++ ) {
            p[i] = new ArrayDeque<int[]>();
        }

        for(int i = 0; i < words.length; i ++ ) {
            p[words[i].charAt(0) - 'a'].offer(new int[]{i, 0});
        }

        int res = 0;
        for(int i = 0; i < s.length(); i ++ ) {
            char c = s.charAt(i);
            int len = p[c - 'a'].size();
            while(len > 0) {
                int[] t = p[c - 'a'].poll();
                if(t[1] == words[t[0]].length() - 1) {
                    res ++ ;
                } else {
                    t[1] ++ ;
                    p[words[t[0]].charAt(t[1]) - 'a'].offer(t);
                }
                len -- ;
            }
        }
        return res;
    }
}
python
class Solution:
    def numMatchingSubseq(self, s: str, words: List[str]) -> int:
        p = defaultdict(list)
        for i, w in enumerate(words):
            p[w[0]].append((i, 0))

        res = 0
        for c in s:
            q = p[c]
            p[c] = []
            for i, j in q:
                j += 1
                if j == len(words[i]):
                    res += 1
                else:
                    p[words[i][j]].append((i, j))

        return res
js
/**
 * @param {string} s
 * @param {string[]} words
 * @return {number}
 */
var numMatchingSubseq = function(s, words) {
    let p = new Array(26).fill(0).map(() => new Array());
    for(let i = 0; i < words.length; i ++ ) {
        p[words[i][0].charCodeAt() - 'a'.charCodeAt()].push([i, 0]);
    }

    let res = 0;
    for(let i = 0; i < s.length; i ++ ) {
        let c = s[i];
        let len = p[c.charCodeAt() - 'a'.charCodeAt()].length;

        while(len > 0) {
            len -- ;
            let t = p[c.charCodeAt() - 'a'.charCodeAt()].shift();
            if(t[1] === words[t[0]].length - 1) {
                res ++ ;
            } else {
                t[1] ++ ;
                p[words[t[0]][t[1]].charCodeAt() - 'a'.charCodeAt()].push(t);
            }
        }
    }
    return res;
};
golang
func numMatchingSubseq(s string, words []string) int {
    type pair struct {
        i int
        j int
    }

    ps := [26][]pair{}
    for i, w := range words {
        ps[w[0] - 'a'] = append(ps[w[0] - 'a'], pair{i, 0})
    }

    res := 0
    for _, c := range s {
        q := ps[c - 'a']
        ps[c - 'a'] = nil
        for _, p := range q {
            p.j ++ 
            if p.j == len(words[p.i]) {
                res ++ 
            } else {
                w := words[p.i][p.j] - 'a'
                ps[w] = append(ps[w], p)
            }
        }
    }
    return res
}

 

标签:792,--,res,++,int,words,auto,LeetCode,size
From: https://www.cnblogs.com/zk6696/p/17537447.html

相关文章

  • 如何快速删除node_modules
    1.windows11操作系统 回到桌面--》右击任务管理器--》运行新任务-  2.--》勾选以管理员身份运行cmd命令 3.--》删除命令帮助helprd  4.删除命令  rd/s/q 盘符:\某个文件夹 如:rd/s/q  E:\webProject\node_modules 这是高危险命令,直接从磁盘上删除当......
  • 动态规划之 01背包问题
    1. 什么是01背包问题?01背包问题是一种经典的组合优化问题,它的描述如下:有n种物品和一个容量为C的背包,每种物品有一个重量w[i]和一个价值v[i],其中i=1,2,…,n。问如何选择物品放入背包,使得背包内的物品总价值最大,且不超过背包的容量?这里的01表示每种物品只能选择放入或不放入,不......
  • 区块链基础知识
    开始学习区块链了,记录一下区块链入门的一些基础知识。1. 区块链区块链本质是一种多方共享的分布式账本技术,存储于其中的数据或信息,具有“不可伪造、不可篡改、全程留痕、可以追溯、公开透明、集体维护”等特征。2.区块区块链中一套分布式账本存储的基本数据结构、是在区块链......
  • ASP.NET Core SignalR 系列(二)- 中心(服务端)
    本章将和大家分享ASP.NETCoreSignalR中的中心(服务端)。本文大部分内容摘自微软官网:https://learn.microsoft.com/zh-cn/aspnet/core/signalr/hubs?view=aspnetcore-7.0废话不多说,我们直接来看一个Demo,Demo的目录结构如下所示:本Demo的Web项目为ASP.NETCoreWeb应用程序(目......
  • 「Python实用秘技15」pandas中基于范围条件进行表连接
    本文完整示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/PythonPracticalSkills这是我的系列文章「Python实用秘技」的第15期,本系列立足于笔者日常工作中使用Python积累的心得体会,每一期为大家带来一个几分钟内就可学会的简单小技巧。作为系列第1......
  • 吊炸天的 Kafka 图形化工具 Eagle,必须推荐给你
    Kafka是当下非常流行的消息中间件,据官网透露,已有成千上万的公司在使用它。最近实践了一波Kafka,确实很好很强大。今天我们来从三个方面学习下Kafka:Kafaka在Linux下的安装,Kafka的可视化工具,Kafka和SpringBoot结合使用。希望大家看完后能快速入门Kafka,掌握这个流行的消息中间件!Kaf......
  • gitlab双重验证的时候没有中国区的解决办法
    打开开发工具,在控制台输入下面的代码运行即可在console中输入:varoption=newOption("China+86","+86");option.selected=true;document.getElementById('country').options.add(option,0);原理,手动更改页面的元素输入手机号,发送验证码,手机就可以收到了。......
  • 基础工具了解----第一课
    目录1.typora(1)安装破解typora(2)配置并尝试利用typora写笔记(3)注册博客园(4)上传笔记2.python+pycharm(1)安装python3.10版本(2)安装破解pycharm专业版(3)环境配置、解释器(4)插件安装1.typora(1)安装破解typora(2)配置并尝试利用typora写笔记(3)注册博客园(4)上传笔记2.pyth......
  • PostgreSQL 简单查询
    对于数据库中数据的常见操作,可以简称为增删改查(CRUD,Create、Retrieve、Update、Delete)。其中,使用最多,也最复杂的功能当属数据查询。根据SQL标准,查询语句使用SELECT关键字表示。单表查询简单查询开始,来看一个示例selectfirst_name,last_namefromemployees;有SQL基础的都......
  • OS库中常用函数用法举例
    在操作系统(OS)的库中,有许多常用函数可用于处理文件、目录、进程等。以下是一些常见函数的用法举例:打开和关闭文件:fopen函数用于打开一个文件,例如FILE*file=fopen("example.txt","r");fclose函数用于关闭文件,例如fclose(file);读写文件:fscanf函数用于从文件......