• 392.判断子序列 | 792.匹配子序列的单词数


    392. 判断子序列

    labuladong 题解思路

    给定字符串 s 和 t ,判断 s 是否为 t 的子序列

    字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace""abcde"的一个子序列,而"aec"不是)。

    进阶:

    如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

    示例 1:

    输入:s = "abc", t = "ahbgdc"
    输出:true
    

    示例 2:

    输入:s = "axc", t = "ahbgdc"
    输出:false

    思路:指针i指向s,指针j指向t,不断向前移动,进行匹配 

    1. class Solution {
    2. public:
    3. bool isSubsequence(string s, string t) {
    4. int i=0;
    5. int j=0;
    6. while(isize()&&jsize())
    7. {
    8. if(s[i]==t[j])
    9. {
    10. i++;
    11. }
    12. j++;
    13. }
    14. return i==s.size();
    15. }
    16. };

    792. 匹配子序列的单词数

    labuladong 题解

    给定字符串 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

    思路:

    首先记录下t的每一个字符和它的对应下标

     

     这样在遍历时,就可以借助 index 中记录的信息,二分搜索 index[c] 中恰好比 j 大的那个数,如下图,在 [0,2,6] 中搜索比 4 大的那个数,即6

     

     注意:如果目标值不存在,那么左侧边界的二分查找会找到恰好比目标值大的最小的数的索引

    1. class Solution {
    2. public:
    3. int numMatchingSubseq(string s, vector& words) {
    4. unordered_map<char,vector<int>> mapping;
    5. int res=0;
    6. for(int i=0;isize();i++)//存储s的每一个字符与它的对应下标
    7. {
    8. mapping[s[i]].push_back(i);
    9. }
    10. for(string word:words)
    11. {
    12. int i=0;
    13. int j=0;//指向s的指针
    14. for(i=0;isize();i++)
    15. {
    16. char c=word[i];
    17. if(mapping.count(c))
    18. {
    19. int index=left_find(mapping[c],j);
    20. if(index==-1)
    21. {
    22. break;
    23. }
    24. else
    25. {
    26. //向前移动指针j
    27. j=mapping[c][index]+1;
    28. }
    29. }
    30. else//word中的字符在s中不存在,则不匹配
    31. {
    32. break;
    33. }
    34. }
    35. if(i==word.size())//word中的字符全部匹配,则是子序列
    36. {
    37. res++;
    38. }
    39. }
    40. return res;
    41. }
    42. //找到mapping[c]中恰好比j大的最小元素的下标索引
    43. int left_find(vector<int>& position,int j)
    44. {
    45. int left=0;
    46. int right=position.size();
    47. while(left
    48. {
    49. int mid=(left+right)/2;
    50. if(position[mid]
    51. {
    52. left=mid+1;
    53. }
    54. else if(position[mid]>j)
    55. {
    56. right=mid;
    57. }
    58. else
    59. {
    60. right=mid;
    61. }
    62. }
    63. //mapping[c]中的元素都比j小,则left左侧边界就会一直向右直至和right相等,退出循环
    64. if(left==position.size())
    65. {
    66. return -1;
    67. }
    68. return left;
    69. }
    70. };
  • 相关阅读:
    BlueTeam 加固
    EfficientDet: Scalable and Efficient Object Detection
    两数之和-leetcode
    一图看懂,阿里云飞天企业版如何支持政企数智创新
    2022 年前端工程师学习路线图(完整版)
    数据库安全性管理
    5.0 nodejs通过thrift连接hbase
    【JavaSE】反射
    你知道聊天机器人在医疗保健行业发挥了什么作用吗?
    【树莓派不吃灰】基础篇⑰ 半小时搭建树莓派4B可运行环境(不需要显示器,不需要网线),配置frp外网密钥ssh登录
  • 原文地址:https://blog.csdn.net/weixin_50437588/article/details/126902318