leetcode 28. 实现 strStr()

问题描述

实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1。
示例 1:
输入: haystack = "hello", needle = "ll"
输出: 2
示例 2:
输入: haystack = "aaaaa", needle = "bba"
输出: -1
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

问题分析

  • 第一种方法:暴力方法,直接双层遍历,在最外层遍历只遍历到n-m+1而不是到n,因为needle的长度为m,后面肯定匹配不上。
  • 第二种方法:Sunday方法,通过记录一个偏移表,防止内层循环还要从头开始遍历。
    • Sunday算法对偏移量定义为:每个字符在串中最后出现的位置。
    • 对匹配规则是这样规定的:
      • 若匹配不成功:
        • 如果匹配串的后一个元素不在模式串中,那么只需要直接在后一个元素之后匹配即可,即游标移动一个模式串长度。
        • 如果匹配串的后一个元素在模式串中,则偏移到对齐位置,再进行比较。
      • 若匹配成功,则返回当前游标。

代码1

class Solution {
public:
    int strStr(string haystack, string needle) {
        if(needle.size() == 0) return 0;
        int n = haystack.size();
        int m = needle.size(),i,j,tmp;
        if(n < m) return -1;
        char c = needle[0];
        for(i = 0; i < n-m+1; i++)
        {
            if(haystack[i] == c)
            {
                tmp = i;
                for(j = 1; j < m;j++)
                {
                    if(haystack[++tmp] != needle[j])
                    break;
                }
                if(j == m)return i;
            }
        } 
        return -1;
    }
};

结果1

执行用时 :8 ms, 在所有 C++ 提交中击败了58.33%的用户
内存消耗 :9.2 MB, 在所有 C++ 提交中击败了32.48%的用户

代码2

class Solution {
public:
    int strStr(string haystack, string needle) {
        if(needle.size() == 0) return 0;
        int n = haystack.size();
        int m = needle.size(),i;
        if(n < m) return -1;
        map<char,int> table;
        for(i = m-1; i >= 0; i--)//构造偏移表
            if(table.find(needle[i]) == table.end())
                table.insert(pair<char,int>(needle[i],m-i));
        for(i = 0; i<n-m+1;)
        {
            if(haystack.substr(i,m) != needle)
            {
                if(table.find(haystack[i+m]) == table.end())
                    i = i + m + 1;//不配配
                else
                    i = i + table.find(haystack[i+m])->second;
            }
            else
                return i;
        }
        return -1;
    }
};

结果2

执行用时 :4 ms, 在所有 C++ 提交中击败了93.65%的用户
内存消耗 :9.6 MB, 在所有 C++ 提交中击败了6.78%的用户
posted @ 2020-02-04 11:45  曲径通霄  阅读(115)  评论(0编辑  收藏  举报