• leetcode.792 匹配子序列的单词数 哈希表 + 二分优化


    792. 匹配子序列的单词数

    目录

    1、c++版 

    2、java


    暴力思路:

    最暴力的思路是双指针 也就是指针i指向s 指针j指向word  

    如果s[i]==word[j] 则将 i 和 j 同时向后移一个

    否则移动 i指针 

    如果i指针指向s末尾时 如果j也同时指向word末尾 则说明是子序列 否则不是

    但该方法时间复杂度会tle 因此要在此基础上进行优化

    二分哈希表优化

    暴力做法里 我们要在不匹配时不断把i指针一个一个向后移 

    我们可以把s中每个字母的下标按从小到大顺序存在哈希表pos里

    比如:【aabccb】  word: "bac"

    则 pos[a]={0,1}

        pos[b]={2,5}

        pos[c]={3,4}

    这样对于需要进行匹配的word[j]  可以通过在pos里进行二分查找 找到第一个大于当前i指针的位置,如果该位置不存在,则说明不匹配,否则之间将i指针移动到当前位置

    比如:

            初始化 i 指针为-1

            word:"bac"

            查找b -> 找到了 -> i指针移向2

            查找a -> 二分后找不到比2大的位置 -> 该位置不存在 -> 不匹配

            word:"abcb"

            查找a -> 找到了 -> i指针移向0

            查找b -> 找到了 -> i指针移向2

            查找c -> 找到了 -> i指针移向3

            查找b -> 找到了 -> i指针移向5 -> 匹配

    1、c++版 

    1. class Solution {
    2. public:
    3. int numMatchingSubseq(string s, vector& words) {
    4. vectorint>> pos(26);
    5. for(int i=0;isize();i++)
    6. pos[s[i]-'a'].push_back(i); //把s中出现的字母 将其位置按从小到大记录
    7. int res=words.size();
    8. for(int i=0;isize();i++)
    9. {
    10. if(words[i].size()>s.size())
    11. {
    12. res--;
    13. continue;
    14. }
    15. int p=-1;
    16. for(int j=0;jsize();j++)
    17. {
    18. auto &ps=pos[words[i][j]-'a']; //获取该字符的pos序列
    19. auto it=upper_bound(ps.begin(),ps.end(),p); //查找比p大的第一个下标位置
    20. if(it==ps.end()) //如果没查找到 则说明不是子序列
    21. {
    22. res--;
    23. break;
    24. }
    25. p=*it; //找到了 p指针向后移
    26. }
    27. }
    28. return res;
    29. }
    30. };

    2、java

    1. class Solution {
    2. public int numMatchingSubseq(String s, String[] words) {
    3. List[] pos=new ArrayList[26];
    4. for(int i=0;i<26;i++) pos[i]=new ArrayList<>();
    5. for(int i=0;i'a'].add(i);
    6. int res=words.length;
    7. for(String w:words)
    8. {
    9. if(w.length()>s.length())
    10. {
    11. res--;
    12. continue;
    13. }
    14. int p=-1;
    15. for(int i=0;i
    16. {
    17. char ch=w.charAt(i);
    18. if(pos[ch-'a'].isEmpty()||pos[ch-'a'].get(pos[ch-'a'].size()-1)<=p) //如果二分位置直接卡出去了
    19. {
    20. res--;
    21. break;
    22. }
    23. p=find(pos[ch-'a'],p);
    24. }
    25. }
    26. return res;
    27. }
    28. public int find(List a,int target)
    29. {
    30. int l=0,r=a.size()-1;
    31. while(l
    32. {
    33. int mid=l+r>>1;
    34. if(a.get(mid)>target) r=mid;
    35. else l=mid+1;
    36. }
    37. return a.get(l);
    38. }
    39. }

  • 相关阅读:
    机器学习之算法部分(算法篇1)
    Python3极简教程(一小时学完)上
    【C++】​——多态性与模板(其一)
    DenseNet网络论文学习笔记
    网络之眼:XSS与CSRF攻击的深度防范
    【Java每日一题】——第四十一题:编写程序描述影视歌三栖艺人。(2023.10.27)
    【王道数据结构编程题】- 二叉树算法练习
    Lua 支持虚函数的解决方案
    BootStrap--的使用方法
    Python BeautifulSoup4 入门使用
  • 原文地址:https://blog.csdn.net/weixin_61639349/article/details/127910984