Implement strStr().

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

分析:该题是经典的串匹配,我们可以用KMP来解,时间复杂度为O(m+n)。关于KMP的详细内容可以参考一下博文http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html。这里,我主要介绍一下运用KMP的几个关键点。

1. 为了避免指针回溯,KMP引入了next数组,用来确定下次匹配时模式串指针的位置。在用next数组前,我们要知道next[j]的含义,便于我们理解和实现。通俗的讲,next[j]表示pattern[0,j-1]中其前缀跟后缀相同的最大长度,我们用下面的式子来帮助理解:

next[0] = -1, next[1] = 0; for j > 1, next[j] = max(k) where  0<k<j and pattern[0,k-1] = pattern[j-k, j-1]。

2. 如何计算next数组,我们可以用动态规划的思想来计算next数组,在计算next[j]时,如果pattern[j-1] = pattern[next[j-1]],那么next[j] = next[j-1] + 1; 否则不匹配,则可以按KMP的做法,用next[j-1]确定下一个匹配的位置(此时模式串和目标串都是pattern[0,j-1])。

3. 在解决上面两个问题后,我们讨论如果通过next数组来做串匹配。在串匹配的时候可分两种情况:

  1) target[i] = pattern[j],说明匹配,我们只需i++, j++。

  2)target[i] != pattern[j], 此时我们需要用next数组确定j的下一个匹配位置。如果next[j] >= 0,则 j = next[j],i位置不便; 如果next[j] == -1,i往后移一步,j置0。

在实现时,2)中next[j] = -1的情况可以跟1)的情况合并。

解决了上面三个讨论,我们就可以写出KMP代码了,如下:

 class Solution {
public:
char *strStr(char *haystack, char *needle) {
return kmp(haystack, needle);
}
char * kmp(char * haystack, char * needle){
int m = strlen(needle);
if(m == ) return haystack;
int * next = (int *)malloc(sizeof(int) * m); compute_next(needle, next);
int i = , k = ; while(i < strlen(haystack)){
if(k == - || haystack[i] == needle[k]){
k++;
i++;
}else k = next[k];
if(k == m) return haystack+i-m;
}
return NULL;
}
void compute_next(char * needle, int * next){
int m = strlen(needle);
next[] = -;
int k = -;
for(int j = ; j < m-;){
if(k == - || needle[j] == needle[k]){
k++;
j++;
next[j] = k;
}else k = next[k];
}
}
};

Leetcode: strStr()的更多相关文章

  1. [LeetCode] Implement strStr() 实现strStr()函数

    Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle ...

  2. [Leetcode] implement strStr() (C++)

    Github leetcode 我的解题仓库   https://github.com/interviewcoder/leetcode 题目: Implement strStr(). Returns ...

  3. [Leetcode][Python]28: Implement strStr()

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 28: Implement strStr()https://oj.leetco ...

  4. [LeetCode]题解(python):028-Implement strStr()

    题目来源: https://leetcode.com/problems/implement-strstr/ 题意分析: 输入两个字符串haystack和needle,如果needle是haystack ...

  5. 【一天一道LeetCode】#28. Implement strStr()

    一天一道LeetCode系列 (一)题目 Implement strStr(). Returns the index of the first occurrence of needle in hays ...

  6. LeetCode专题-Python实现之第28题: Implement strStr()

    导航页-LeetCode专题-Python实现 相关代码已经上传到github:https://github.com/exploitht/leetcode-python 文中代码为了不动官网提供的初始 ...

  7. 【算法】LeetCode算法题-Implement strStr

    这是悦乐书的第151次更新,第153篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第10题(顺位题号是28).给定两个任意字符串haystack.needle,返回hay ...

  8. Leetcode : eImplement strStr

    Leetcode : eImplement strStr 描述 对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个 ...

  9. 乘风破浪:LeetCode真题_028_Implement strStr()

    乘风破浪:LeetCode真题_028_Implement strStr() 一.前言     这次是字符串匹配问题,找到最开始匹配的位置,并返回. 二.Implement strStr() 2.1 ...

随机推荐

  1. iframe 父子窗口相互之间调用语法

    一.父窗口调用iframe子窗口方法 1.HTML语法:<iframe name="myFrame" src="child.html"></i ...

  2. ThinkPHP3.2.2中开启REWRITE模式

    1. 在项目配置文件(\Application\Common\Conf\config.php)中配置URL模式 <?php return array( //URL模式 , ); 2. 在Thin ...

  3. oracle 查询今天哪个表增加的数据多

    一.创建一个表  create table A(  TABLE_NAME VARCHAR2(200),  COUNT_NUM  NUMBER) 二.创建一个存储过程create or replace  ...

  4. core java 8~9(GUI & AWT事件处理机制)

    MODULE 8 GUIs--------------------------------GUI中的包: java.awt.*; javax.swing.*; java.awt.event.*; 要求 ...

  5. Swift弹窗

    在一个ViewController中使用以下代码: let alertController = UIAlertController(title: "Game Set", messa ...

  6. ExtJS4.x 开发环境搭建

    需要的资源 ExtJS4.2 eclipse 开发环境搭建 在项目中国需要引用的文件: eclipse中有报错.需要处理的是ext-lang-zh_CN.js,中文编码不能识别.右键->属性-& ...

  7. Mysql去除重复

    常用的有两种方法,第一种就是select distinct name from table.但是有时候我们要返回多个字段时就用第二种方法select *, count(distinct name) f ...

  8. Photoshop/PS中如何写维吾尔语等语言 乱码

    在新疆的朋友都了解很多标语上面都会有汉语.维语等两种语言.有很多维吾尔语.哈萨克语.柯尔克孜语等语言 要在PS 里进行设计处理,这时在Photoshop中进行设计时文字粘贴进来后出现不正常是乱码形式. ...

  9. Cocos2dx中利用双向链表实现无限循环滚动层

    [Qboy原创] 在Cocos2dX 3.0 中已经实现一些牛逼的滚动层,但是对于有一些需要实现循环滚动的要求确没有实现,笔者在前段时间的一个做了一个游戏,需求是实现在少有的(13个)英雄中进行循环滚 ...

  10. DF与EF的区别

    DF:专有文件 EF:基本文件 1.EF没有文件名,只有FID(文件标识符) 2.DF有文件名,又有FID,因此COS可以根据文件名来访问DF