LeetCode 每日一题「实现 strStr()」

简介: LeetCode 每日一题「实现 strStr()」
我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「 陈皮的JavaLib」第一时间阅读最新文章,回复【 资料】,即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板。

@TOC

题目


实现 strStr() 函数。给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。当 needle空字符串 时我们应当返回 0

示例1:

  • 输入: haystack = "hello", needle = "ll"
  • 输出:2

示例2:

  • 输入:haystack = "aaaaa", needle = "bba"
  • 输出:-1

示例3:

  • 输入:haystack = "aaaaa", needle = ""
  • 输出:0

题目来源:LeetCode


分析


字符串匹配,最简单的,无非暴力匹配,但这效率是最低的。

如果不自己实现,现有很多 api 也都实现了此功能,例如 StringindexOf 方法就能达到此效果。

但是此题目是让我们自己实现,说到字符串匹配问题,最有名的无非是 KMP算法

KMP算法核心思想是用模式串(即本题目的needle)构建一个next数组

  • next 数组各值的含义:代表当前字符之前的字符串中,有多大长度的相同前缀
  • 例如如果 next[j] = k,代表 j 之前的字符串中有最大长度为 k 的相同前缀。
  • 意味着在某个字符失配时,该字符对应的 next 值会告诉你下一步匹配中,模式串应该跳到哪个位置(跳到 next[j] 的位置)。
  • 如果 next[j] 等于0,则跳到模式串的开头字符,若 next[j] = k 且 k > 0,代表下次匹配跳到j之前的某个字符,而不是跳到开头,即跳过了 k 个字符。


实现


package com.chenpi;

/**
 * @Description 实现 strStr()
 * @Author Mr.nobody
 * @Date 2021/1/23
 * @Version 1.0
 */
public class StrStr {

    public static int strStr(String haystack, String needle) {
        // 文本串长度小于模式串,明显匹配不到
        if (haystack.length() < needle.length()) {
            return -1;
        }
        // 利用 KMP 算法构建 next 数组
        int[] next = buildNext(needle);
        int i = 0, j = 0;
        while (i < haystack.length() && j < needle.length()) {
            if (haystack.charAt(i) == needle.charAt(j)) {
                // 匹配,两个下标都向后
                j++;
                i++;
            } else if (j == 0) {
                // 开头处匹配失效
                i++;
            } else {
                // 利用 KMP,回溯到具体位置
                j = next[j];
            }
        }
        return j == needle.length() ? i - j : -1;
    }

    // KMP算法
    // next数组各值的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀。
    // 例如如果next[j]=k,代表j之前的字符串中有最大长度为k的相同前缀后缀。
    // 意味着在某个字符失配时,该字符对应的next值会告诉你下一步匹配中,模式串应该跳到哪个位置(跳到next[j]的位置)。
    // 如果next[j]等于0,则跳到模式串的开头字符,若next[j]=k且k>0,代表下次匹配跳到j之前的某个字符,而不是跳到开头,即跳过了k个字符。
    private static int[] buildNext(String needle) {
        // 记录模式串needle每个字符匹配失效后应该回溯的位置,即next[j]为在j处匹配失效后,下一个匹配(回溯)的位置,
        int[] next = new int[needle.length()];
        int j;
        // 因为第0个字符匹配失效,肯定还是从0个字符开始,所以i的从1开始
        for (int i = 1; i < needle.length(); i++) {
            j = i - 1;
            while (j > 0 && needle.charAt(i - 1) != needle.charAt(next[j])) {
                j = next[j];
            }
            if (j <= 0) {
                next[i] = 0;
            } else {
                next[i] = next[j] + 1;
            }
        }
        return next;
    }

    public static void main(String[] args) {
        System.out.println(strStr("hello", "ll"));
        System.out.println(strStr("aaaaa", "bba"));
        System.out.println(strStr("aaaaa", ""));
    }
}


输出结果

2
-1
0


Leetcode执行结果
在这里插入图片描述

上一题与下一题


上一题LeetCode 每日一题「数组形式的整数加法」

下一题LeetCode 每日一题「判定字符是否唯一」

相关文章
|
9月前
|
算法
LeetCode-28 实现strStr() KMP算法的学习
LeetCode-28 实现strStr() KMP算法的学习
|
11月前
|
算法 安全 Java
LeetCode - #28 实现 strStr()
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
|
11月前
|
算法 Java C语言
leetcode:28.实现strStr()
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
44 0
leetcode 28 找出字符串第一个匹配的下标(KMP实现strStr)
leetcode 28 找出字符串第一个匹配的下标(KMP实现strStr)
60 0
leetcode 28 找出字符串第一个匹配的下标(KMP实现strStr)
|
Java C语言
LeetCode 28. 实现 strStr()
实现 strStr() 函数。
76 0
|
程序员
【Leetcode】225. 用队列实现栈、232. 用栈实现队列
【Leetcode】225. 用队列实现栈、232. 用栈实现队列
88 0
【Leetcode】225. 用队列实现栈、232. 用栈实现队列
|
存储 前端开发 算法
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
132 0
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
代码随想录刷题|LeetCode 栈和队列的理论基础 232.用栈实现队列 225. 用队列实现栈
代码随想录刷题|LeetCode 栈和队列的理论基础 232.用栈实现队列 225. 用队列实现栈
代码随想录刷题|LeetCode 栈和队列的理论基础 232.用栈实现队列 225. 用队列实现栈
|
存储 算法 索引
代码随想录刷题|LeetCode KMP算法理论 28. 实现 strStr() 459.重复的子字符串
代码随想录刷题|LeetCode KMP算法理论 28. 实现 strStr() 459.重复的子字符串
代码随想录刷题|LeetCode KMP算法理论 28. 实现 strStr() 459.重复的子字符串
leetcode 用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty): 实现 MyQueue 类: void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int peek() 返回队列开头的元素 boolean empty() 如果队列为空,返回 true ;否则,返回 false
48 0

热门文章

最新文章