字符串——28. 实现 strStr()

简介: 本专栏按照数组—链表—哈希—字符串—栈与队列—二叉树—回溯—贪心—动态规划—单调栈的顺序刷题,采用代码随想录所给的刷题顺序,一个正确的刷题顺序对算法学习是非常重要的,希望对大家有帮助

1 题目描述

  1. 实现 strStr()

实现 strStr() 函数。

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

2 题目示例

示例 1:
输入:haystack = "hello", needle = "ll"
输出:2

示例 2:
输入:haystack = "aaaaa", needle = "bba"
输出:-1

3 题目提示

1 <= haystack.length, needle.length <= 104
haystack 和 needle 仅由小写英文字符组成

4 思路

本题是经典的字符串单模匹配的模型,因此可以使用字符串匹配算法解决,常见的字符串匹配算法包括暴力匹配、Knuth-Morris-Pratt算法、Boyer-Moore算法、Sunday 算法等,本文将讲解Knuth-Morris-Pratt算法。
因为哈希方法可能出现哈希值相等但是字符串不相等的情况,而strStr函数要求匹配结果必定正确,因此本文不介绍哈希方法,有兴趣的读者可以自行了解滚动哈希的实现(如Rabin-Karp算法)。
方法一:暴力匹配思路及算法
我们可以让字符串needle 与字符串haystack的所有长度为m的子串均匹配一次。
为了减少不必要的匹配,我们每次匹配失败即立刻停止当前子串的匹配,对下一个子串继续匹配。如果当前子串匹配成功,我们返回当前子串的开始位置即可。如果所有子串都匹配失败,则返回—1。
复杂度分析
时间复杂度:o(n x m),其中n是字符串hagystack的长度,m是字符串needle的长度。最坏情况下我们需要将字符串needle与字符串haystack的所有长度为m的子串均匹配一次。
空间复杂度:O(1)。我们只需要常数的空间保存若干变量。
方法二:KMP
介绍不说了,太长,大家可以自己搜索一下

5 我的答案

方法一:暴力

class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length(), m = needle.length();
        for (int i = 0; i + m <= n; i++) {
            boolean flag = true;
            for (int j = 0; j < m; j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                return i;
            }
        }
        return -1;
    }
}

方法二:KMP

class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length(), m = needle.length();
        if (m == 0) {
            return 0;
        }
        int[] pi = new int[m];
        for (int i = 1, j = 0; i < m; i++) {
            while (j > 0 && needle.charAt(i) != needle.charAt(j)) {
                j = pi[j - 1];
            }
            if (needle.charAt(i) == needle.charAt(j)) {
                j++;
            }
            pi[i] = j;
        }
        for (int i = 0, j = 0; i < n; i++) {
            while (j > 0 && haystack.charAt(i) != needle.charAt(j)) {
                j = pi[j - 1];
            }
            if (haystack.charAt(i) == needle.charAt(j)) {
                j++;
            }
            if (j == m) {
                return i - m + 1;
            }
        }
        return -1;
    }
}
相关文章
|
Python
Python量化炒股的数据信息获取— 获取上市公司股东和股本信息
Python量化炒股的数据信息获取— 获取上市公司股东和股本信息
711 1
|
9月前
|
机器学习/深度学习 人工智能 算法
《量子比特:AI复杂算法破局的关键力量》
在科技迅猛发展的时代,量子计算与人工智能(AI)成为推动人类进步的双引擎。量子比特作为量子计算的核心,凭借叠加态和纠缠特性,展现出超越传统比特的独特优势。它能同时处理多种状态,大幅提升复杂AI算法的效率,如加速图像识别、语义分析及优化问题求解。尽管量子技术仍面临挑战,但其潜力将为AI注入新活力,推动智能化社会的到来。
161 17
|
JavaScript 算法 前端开发
国标哈希算法基础:SHA1、SHA256、SHA512、MD5 和 HMAC,Python和JS实现、加盐、算法魔改
国标哈希算法基础:SHA1、SHA256、SHA512、MD5 和 HMAC,Python和JS实现、加盐、算法魔改
1669 1
|
安全 Linux KVM
ARM系列 -- 虚拟化(一)
ARM系列 -- 虚拟化(一)
378 0
|
网络协议 Ubuntu Linux
飞腾CPU如何使用PXE方式安装麒麟桌面系统?
飞腾CPU如何使用PXE方式安装麒麟桌面系统?
4724 0
飞腾CPU如何使用PXE方式安装麒麟桌面系统?
|
Ubuntu Windows
iperf3 使用
iperf3 使用
596 0
iperf3 使用
|
安全 网络协议 Java
kali工具详细讲解
Kali系统预装了大量的安全工具,可以说是一个安全工具的数据库。在kali2018.2系统中就有600多个工具,工具如此之多,掌握所有的工具是不现实的,只有需要用的时候再去学习工具的使用即可。但是了解这些工具的用途,掌握一些常用的安全工具是必要的,本篇文章主要对一些常用的安全工具进行介绍,这里只需要简单地了解一下这些工具的用途和使用方法,在后边的文章中将会用到这些工具完成相应的实操,还会具体讲解这些工具的使用。
如何用NotePad++查看二进制文件
如何用NotePad++查看二进制文件
2553 0
如何用NotePad++查看二进制文件
|
网络协议 Windows
Win系统 - NETSH WINSOCK RESET
Win系统 - NETSH WINSOCK RESET
687 0
|
监控 关系型数据库 Linux