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.

Update (2014-11-02):

The signature of the function had been updated to return the index instead of the pointer. If you still see your function signature returns a char * or String, please click the reload button to reset your code definition.

分析

这是一道模式匹配算法,给定两个字符串haystack与needle,给出needle在haystack完全匹配的首位置坐标(从0开始)。

这道题在数据结构中有讲解,除了开始的简单模式匹配算法BF算法,还给出了改进后的KMP经典算法,下面分别用这两个算法实现。

AC代码

class Solution {
public:
    //简单模式匹配算法(BF算法)
    int strStr(string haystack, string needle) {
        int len = strlen(haystack.c_str()), nl = strlen(needle.c_str());

        int i = 0, j = 0;
        while (i < len && j < nl)
        {
            if (haystack[i] == needle[j])
            {
                i++;
                j++;
            }
            else{
                i = i - j + 1;
                j = 0;
            }//else
        }//while

        if (j == nl)
            return i - nl;
        else
            return -1;
    }
};

KMP算法实现

class Solution {
public:
    //简单模式匹配算法(BF算法)
    int strStr(string haystack, string needle) {
        int len = strlen(haystack.c_str()), nl = strlen(needle.c_str());

        int i = 0, j = 0;
        while (i < len && j < nl)
        {
            if (haystack[i] == needle[j])
            {
                i++;
                j++;
            }
            else{
                i = i - j + 1;
                j = 0;
            }//else
        }//while

        if (j == nl)
            return i - nl;
        else
            return -1;
    }

    //从字符串haystack的第pos个位置开始匹配
    int KMP(const string &haystack, const string &needle, int pos)
    {
        int len = strlen(haystack.c_str()), nl = strlen(needle.c_str());

        int i = pos, j = 0;
        int *n = Next(needle);
        while (i < len && j < nl)
        {
            if (j == -1 || haystack[i] == needle[j])
            {
                i++;
                j++;
            }
            else{
                j = n[j];
            }//else
        }//while

        if (j == nl)
            return i - nl;
        else
            return -1;

    }

    int* Next(const string &s)
    {
        int i = 0, j = -1;
        int next[500] ;
        int len = strlen(s.c_str());
        next[0] = -1;;
        while (i < len)
        {
            while (j >-1 && s[i] != s[j])
                j = next[j];
            i++;
            j++;

            if (s[i] == s[j])
                next[i] = next[j];
            else
                next[i] = j;
        }//while
        return next;
    }
};

GitHub测试程序源码

时间: 2024-09-30 10:35:44

LeetCode(28)Implement strStr()的相关文章

Leetcode(10)-实现strStr()

实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存在,则返回  -1. 当 needle 是空字符串时我们应当返回 0 . 一开始的思路:用i和j从头开始分别遍历haystack和needle字符串,先固定j,直到i所指的字母与needle的首字符相等的时候,停止遍历.然后i和j开始同时向后遍历,如果有不相等的,就返回-1,直到有一个字符串先到头.若hay

HTML5移动开发之路(28)—— JavaScript回顾3

本文为 兄弟连IT教育 机构官方 HTML5培训 教程,主要介绍:HTML5移动开发之路(28)-- JavaScript回顾3 一.基本数据类型 number:数字类型 string:字符串 (注意s小写:string是基本类型) boolean:布尔类型   //前三个都有对应的包装类 null:空类型 undefined:未定义类型 测试一: [html] view plain copy print? <html> <!--基本类型测试--> <head> <

Android菜鸟的成长笔记(28)——Google官方对Andoird 2.x提供的ActionBar支持

在Google官方Android设计指南中(链接:http://www.apkbus.com/design/get-started/ui-overview.html)有一个新特性就是自我标识,也就是宣传自己,所以很多应用现在也自然的使用ActionBar并提供自己的logo. 微信的应用: Google的Android设计指南中是这样说的:应用的 启动图标 作为启动应用的入口是展示 logo 的最佳场所.你也可以将启动图标放置在 操作栏 上,从而保证在应用内的所有页面上都能看到它. 在使用Act

Leetcode(4)寻找两个有序数组的中位数

Leetcode(4)寻找两个有序数组的中位数 [题目表述]: 给定两个大小为 m 和 n 的有序数组 nums1 和* nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1* 和 nums2 不会同时为空. 第一种方法:list拼接排列取中位数 执行用时:116 ms : 内存消耗:11.8MB 效果:还行 class Solution(object): def findMedianSortedArrays(self,

Leetcode(5)最长回文子串

Leetcode(4)寻找两个有序数组的中位数 [题目表述]: 给定一个字符串 s,找到 s 中 最长 的回文子串.你可以假设 s 的最大长度为 1000.' 第一种方法:未完成:利用回文子串的特点 一开始我的思路如下:回文子串的特点是首尾字母相同,所以我对每一个字母都找到位于它后面的相同字母,利用切片判断这一段是否为回文子串(str[i:j]==str[i:j][::-1]).时间复杂度很高,主要是因为str.find操作非常耗时. class Solution(object): def lo

Leetcode(1)两数之和

Leetcode(1)两数之和 [题目表述]: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标.你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中同样的元素. 第一种方法:暴力 执行用时:5352 ms: 内存消耗:12.9MB 效果:非常差 class Solution(object): def twoSum(self, nums, target): """ :type nums:

Leetcode(2)两数相加

Leetcode(2)两数相加 [题目表述]: 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和.您可以假设除了数字 0 之外,这两个数都不会以 0 开头. 第一种方法:大众解法 执行用时:80 ms: 内存消耗:12.2MB # Definition for singly-linked list. # class ListNode(object

Leetcode(3)无重复字符的最长子串

Leetcode(3)无重复字符的最长子串 [题目表述]: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 第一种方法:暴力 执行用时:996 ms: 内存消耗:12.9MB 效果:太差 class Solution(object): def lengthOfLongestSubstring(self, s): """ :type s: str :rtype: int """ Maxsize=0 res='' if len(s)

Leetcode(9)回文数

Leetcode(9)回文数 [题目表述]: 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 第一次:直接全部转 执行用时:148 ms: 内存消耗:13.4MB 效果:还行 class Solution: def isPalindrome(self, x: int) -> bool: s=str(x) if s==s[::-1]: return True else: return False 第二种方法:反转一半数字 执行用时:156 ms: 内存消耗