• LeetCode392. 判断子序列


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

    提示:

    • 0 <= s.length <= 100
    • 0 <= t.length <= 10^4
    • 两个字符串都只由小写字符组成。

    思路还是挺简单的, 使用C语言更能体现出思路。

    1. 取出s字符串中的一个字符
    2. 取出t字符串中的一个字符
    3. 匹配这2个字符的值
      1. 字符一致,s字符后移,取下一个;t字符后移,取下一个
      2. 字符不一致,t字符后移,取下一个
    4. 最终结束的时候,
      1. 如果s字符串在结束位置,说明匹配成功,返回true
      2. 如果s字符串不在结束位置,说明是t字符先结果,匹配失败,返回false 
    1. bool isSubsequence(char * s, char * t){
    2. int i=0,j=0;
    3. for (;s[i]!='\0' && t[j]!='\0';) {
    4. char sChar = s[i];
    5. char tChar = t[j];
    6. if (sChar == tChar) {
    7. i++;
    8. }
    9. t++;
    10. }
    11. if (s[i]=='\0') {
    12. return true;
    13. }
    14. return false;
    15. }

     使用swift也是同样的思路,但是swift中的字符串确实不好用,写起来没有c语言简洁思路清晰。

    1. class Solution {
    2. func isSubsequence(_ s: String, _ t: String) -> Bool {
    3. var s = s
    4. if s.isEmpty { return true }
    5. for char in t {
    6. if let sFirst = s.first, sFirst == char {
    7. s.removeFirst()
    8. }
    9. if s.isEmpty {
    10. return true
    11. }
    12. }
    13. return false
    14. }
    15. }

    2种算法的时间复杂度都是O(N) ,空间复杂度都是O(1).

    对于思考题,

    思路1:

    把T所有的可能列举出来,然后构造成一个集合,后续的结果只需要匹配集合中有没有子串即可。

    比如 T=“abc”, 列举出所有就是8种组合,“”, “a”,“b”,“c”,“ab”,“ac”,“bc”,“abc”,

    然后估算了一下,t的长度是10^4,  枚举出来结果的数量得有 2^n,n=10^4, 这个数太大了,已经算不出来了,2^100次方用科学计数法表示是1.27x10^30, 已经30个零了。

    此方法想想就行,打住打住。只有t的长度比较小的时候才能发挥作用。

    思路2:

    由于S很多,而T不变,所以要深度挖掘T的潜力,由于总共只有26个字母,可以根据T构造出26个数组,

    以下面的数据为例,“dbceafcdbf” ,  比如A数组中存放的是所有a字母出现的位置,A={5},  B={2,9},C={3,7},D={1,8}, ...

    这样出现一个S时,不需要遍历寻找T中对应的匹配的位置,只需要从对应字母的数组中查位置即可,跳跃式的查找结果,时间复杂度和T的长度无关,只和S的长度有关。而S的长度小于100,如此看来,此方法还是大有可为的。

    总结一下思路:

    1. 根据T字符串生成一系列数组,
    2. 遍历S字符串,
    3. 已S字符串的单个字符作为key,从对应的数组中找匹配的最小下表
      1. 能找到,更新T的查找进度,下次从最小下表+1继续查
      2. 找不到,说明不匹配,返回false
    4. 能遍历完S, 说明是子序列,返回true

    生成的数组长这样

    {
    "a":[1,2],
    "b":[4,7],
    "c":[3,5],
    "d":[6],
    ......
    }

    swift 参考代码如下:

    1. class Solution {
    2. var dic: [Character:Array<Int>]!
    3. func configTDic(t: String) {
    4. // 构造t组成的数组,简单写个json示意一下,只需要生成依次即可
    5. /*
    6. {
    7. "a":[1,2],
    8. "b":[4,7],
    9. "c":[3,5],
    10. "d":[6],
    11. }
    12. */
    13. var dic = [Character:Array<Int>]()
    14. for (idx,tChar) in t.enumerated() {
    15. if var array = dic[tChar] {
    16. array.append(idx)
    17. dic[tChar] = array
    18. } else {
    19. var array = [Int]()
    20. array.append(idx)
    21. dic[tChar] = array
    22. }
    23. }
    24. self.dic = dic
    25. }
    26. func isSubsequence(_ s: String, _ t: String) -> Bool {
    27. if self.dic == nil {
    28. self.configTDic(t: t)
    29. }
    30. var tempDic = self.dic!
    31. // tIndex记录查询到t的下表
    32. var tIndex = 0
    33. for (_,sChar) in s.enumerated() {
    34. if let array = tempDic[sChar] {
    35. // 比如数组是[1,5,7],tIndex=3, 此时需要舍弃1,取5,并把tIndex更新成6
    36. let filterArray = array.filter { value in
    37. value >= tIndex
    38. }
    39. // 数组中找不到合适值,T中没有对应字符,返回false
    40. if filterArray.isEmpty {
    41. return false
    42. }
    43. // filterArray.first中的字符已经使用了,下次匹配不能再使用同一字符
    44. tIndex = filterArray.first! + 1
    45. tempDic[sChar] = filterArray
    46. } else {
    47. // 取不出数组,说明T中没有这个字母,返回false
    48. return false
    49. }
    50. }
    51. return true
    52. }
    53. }

     虽然单次看效率不高,但是针对思考题的场景,应该是能优化很多。

  • 相关阅读:
    这本springMVC源代码分析与实战,阿里P9看了都说源代码分析透了
    115道高频Java面试题,
    vue-使用input封装上传文件图片全局组件
    python+nodejs+vue医院信息管理系统
    android逆向工程反编译指南(详细教程)
    自动化测试 —— Pytest fixture及conftest详解!
    uniapp 使用了uview 的dropdown下拉菜单后出现页面无法滚动
    python-turtle库
    单目标应用:基于白鲨优化算法(WSO)优化极限学习机(ELM)的数据预测(ELM隐藏层神经元可修改,提供MATLAB代码)
    表结构及索引设计
  • 原文地址:https://blog.csdn.net/u014600626/article/details/128138074