• [LeetCode] 28. Implement strStr() 解题思路


    Implement strStr().

    Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

    问题:实现 strStr() 函数。即在  haystack 中匹配 needle 字符串。

    可以理解为,实际上这道题是在问如何实现 KMP(Knuth–Morris–Pratt) 算法。这是个效率比较高的算法,只需要扫一遍 haystack 就可以得到结果,耗时 O(n) 。在扫之前需要做的是对 needle 字符串预处理,得到 needle 各个前缀字符串[0...i]中 既是真实前缀又是真实后缀的子字符串的最长长度。理解这句话,需要注意的是“既是真实前缀又是真实后缀” 是指在某一 needle前缀而言的。

    需要详细理解 KMP 算法,可以参考前一篇文章我所理解的 KMP(Knuth–Morris–Pratt) 算法,或许有帮助。

     1 vector<int> LofPS;
     2 
     3 /**
     4  * 求 s 中所有前缀字符串[0...i]各自的 既是真实前缀又是真实后缀的子字符串最长长度,存于 LofPS[i]。
     5  *
     6  * 例如令 len = LofPS[i],则表示 真实前缀s[0...len-1] 和 真实后缀s[ i-len+1...i ] 相等。
     7  *
     8  */
     9 vector<int> computePrefixSuffix(string s){
    10     
    11     // LofPS[i] 表示 s[0....i] 部分中,既是真实前缀又是真实后缀的子字符串最长长度。
    12     vector<int> LofPS(s.size());
    13     
    14     if (s.size() == 0) {
    15         return LofPS;
    16     }
    17     
    18     LofPS[0] = 0;
    19     
    20     int len = 0;
    21     int i = 1;
    22     
    23     while (i < s.size()) {
    24         
    25         if (s[i] == s[len]) {
    26             len++;
    27             LofPS[i] = len;
    28             i++;
    29             continue;
    30         }
    31                 
    32         if (len != 0) {
    33             // 利用之前计算的结果。这里是一个需要理解的点。
    34             // 根据已计算的 LofPS[len-1]部分 真实前缀、真实后缀的相等的最长长度,定位同样匹配 s 前缀但是更短的子字符串。
    35             len = LofPS[len - 1];
    36         }else{
    37             LofPS[i] = 0;
    38             i++;
    39         }
    40     }
    41     
    42     return LofPS;
    43 }
    44 
    45 
    46 int strStr(string haystack, string needle) {
    47     
    48     // 计算 needle 中所有前缀字符串[0...idx]各自的真实前缀且是真实后缀的最长长度。
    49     vector<int> tmp(needle.size());
    50     LofPS = tmp;
    51     
    52     LofPS = computePrefixSuffix(needle);    
    53     
    54     int i = 0 ;
    55     int k = 0;
    56 
    57     while (i < haystack.size() && k < needle.size()) {
    58         if (haystack[i] == needle[k]) {
    59             i++;
    60             k++;
    61             continue;
    62         }
    63         
    64         if (LofPS[k-1] != 0) {
    65             k = LofPS[k-1];
    66             continue;
    67         }
    68         
    69         if (haystack[i] == needle[0]) {
    70             k = 1;
    71             i++;
    72         }else{
    73             k = 0;
    74             i++;
    75         }
    76     }
    77 
    78     if (k == needle.size()) {
    79         return i - k;
    80     }else{
    81         return -1;
    82     }
    83 }
  • 相关阅读:
    ArrayList和Vector的区别?HashMap和Hashtable的区别?
    试题:关键字public, private, protected的区别?以及不写时默认是什么?
    试题:用JavaScript实现密码验证功能
    RPC和RMI的区别(Difference Between RPC and RMI)
    js中从blob提取二进制
    netty 3.9.2 UDP协议服务器和客户端DEMO
    Java NIO的多路复用及reactor
    android屏蔽home键的实现
    搜索引擎对相似图片搜索识别的原理(一)
    代理模式(设计模式)
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5077297.html
Copyright © 2020-2023  润新知