zoukankan      html  css  js  c++  java
  • [Leetcode] Implement strStr()

    Implement strStr().

    Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.

    KMP算法!

     1 class Solution {
     2 public:
     3     void getNext(vector<int> &next, string &needle) {
     4         int i = 0, j = -1;
     5         next[i] = j;
     6         while (i != needle.length()) {
     7             while (j != -1 && needle[i] != needle[j]) j = next[j];
     8             next[++i] = ++j;
     9         }
    10     }
    11     int strStr(string haystack, string needle) {
    12         if (haystack.empty()) return needle.empty() ? 0 : -1;
    13         if (needle.empty()) return 0;
    14         vector<int> next(needle.length() + 1);
    15         getNext(next, needle);
    16         int i = 0, j = 0;
    17         while (i != haystack.length()) {
    18             while (j != -1 && haystack[i] != needle[j]) j = next[j];
    19             ++i; ++j;
    20             if (j == needle.length()) return i - j;
    21         }
    22         return -1;
    23     }
    24 };

    上面的是通常用的KMP算法,但是算法是有一定缺陷的。比如我们的模式串  pattern =“AAAAB”,其中很容易得到next数组为01230。如果目标匹配串为 “AAAACAAAAB” ,大家可以模拟一下,A要回溯多次。就是说我们的next数组优化并不彻底。优化算法:next[i]表示匹配串在i处如果匹配失败下次移到的位置。下面是优化后的的求next数组的代码。虽然两种写求得next值不一样,但是kmp函数的写法是一样的。

     1 class Solution {
     2 public:
     3     void getNext(vector<int> &next, string &needle) {
     4         int i = 0, j = -1;
     5         next[i] = j;
     6         while (i < needle.length() - 1) {
     7             while (j != -1 && needle[i] != needle[j]) j = next[j];
     8             ++i; ++j;
     9             //特殊情况,这里即为优化之处。考虑下AAAAB, 防止4个A形成0123在匹配时多次迭代。
    10             if (needle[i] == needle[j]) next[i] = next[j]; 
    11             else next[i] = j;
    12         }
    13     }
    14     int strStr(string haystack, string needle) {
    15         if (haystack.empty()) return needle.empty() ? 0 : -1;
    16         if (needle.empty()) return 0;
    17         vector<int> next(needle.length() + 1);
    18         getNext(next, needle);
    19         int i = 0, j = 0;
    20         while (i != haystack.length()) {
    21             while (j != -1 && haystack[i] != needle[j]) j = next[j];
    22             ++i; ++j;
    23             if (j == needle.length()) return i - j;
    24         }
    25         return -1;
    26     }
    27 };

    下面不是KMP算法,但是代码特别简洁:

     1 class Solution {
     2 public:
     3     int strStr(string haystack, string needle) {
     4         int i, j;
     5         for (i = j = 0; i < haystack.size() && j < needle.size();) {
     6             if (haystack[i] == needle[j]) {
     7                 ++i; ++j;
     8             } else {
     9                 i -= j - 1; j = 0;
    10             }
    11         }
    12         return j != needle.size() ? -1 : i - j;
    13     }
    14 };
  • 相关阅读:
    Nginx 日志格式配置介绍
    Java Spring cron表达式使用详解
    Elasticsearch Query DSL
    Elasticsearch Search APIs
    网易2016研发工程师编程题:小易的升级之路
    2016奇虎360研发工程师内推笔试编程题:找镇长
    2016奇虎360研发工程师内推笔试编程题:找到字符串第一个只出现一次的字符
    lintcode: 最长无重复字符的子串
    lintcode :同构字符串
    lintcode : 跳跃游戏
  • 原文地址:https://www.cnblogs.com/easonliu/p/3660748.html
Copyright © 2011-2022 走看看