力扣经典150题第二十三题:找出字符串中第一个匹配项的下标

简介: 力扣经典150题第二十三题:找出字符串中第一个匹配项的下标

力扣经典150题解析之二十三:找出字符串中第一个匹配项的下标

1. 介绍

字符串处理中,查找第一个匹配项的下标是一个常见且基础的问题。这个问题在算法面试和日常编程中经常遇到。本文将介绍如何解决这一问题并给出相应的代码实现。

2. 问题描述

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。

示例 1:

输入:haystack = “sadbutsad”, needle = “sad

输出:0

解释:“sad” 在下标 0 和 6 处匹配。

第一个匹配项的下标是 0 ,所以返回 0 。

示例 2:

输入:haystack = “leetcode”, needle = “leeto”

输出:-1

解释:“leeto” 没有在 “leetcode” 中出现,所以返回 -1 。

提示:

1 <= haystack.length, needle.length <= 104

haystack 和 needle 仅由小写英文字符组成

3. 示例

示例输入:

haystack = "hello world"
needle = "world"

示例输出:

6

在目标字符串 “hello world” 中,子字符串 “world” 第一次出现在下标 6 的位置。

4. 解题思路

我们可以使用字符串匹配的经典算法来解决这个问题。一种简单的方法是使用暴力匹配算法:

  • 遍历目标字符串,对每个可能的起始位置进行匹配。
  • 每次匹配时,对比目标字符串中从当前起始位置开始的子字符串和待匹配的子字符串是否相同。
  • 如果找到匹配,返回当前起始位置;否则继续遍历。

这种方法的时间复杂度是 O(n * m),其中 n 是目标字符串的长度,m 是待匹配的子字符串的长度。

5. 代码实现

public class Solution {
    public int firstIndexOf(String haystack, String needle) {
        int n = haystack.length();
        int m = needle.length();
        
        for (int i = 0; i <= n - m; i++) {
            int j;
            for (j = 0; j < m; j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    break;
                }
            }
            if (j == m) {
                return i;
            }
        }
        
        return -1; // 未找到匹配项
    }
}

6. 复杂度分析

  • 时间复杂度:O(n * m),其中 n 是目标字符串的长度,m 是待匹配的子字符串的长度。在最坏情况下,需要遍历所有可能的子字符串位置。
  • 空间复杂度:O(1),仅使用常数级别的额外空间。

7. 测试与验证

我们对示例输入进行测试:

public class Main {
    public static void main(String[] args) {
        Solution solution = new Solution();
        String haystack = "hello world";
        String needle = "world";
        int result = solution.firstIndexOf(haystack, needle);
        System.out.println("匹配项的下标为:" + result);
    }
}

输出结果为:

匹配项的下标为:6

8. 总结

通过实现字符串匹配算法,我们可以有效地找出字符串中第一个匹配项的下标。在实际应用中,字符串匹配是一个常见且重要的问题。这里我们使用了简单的暴力匹配算法,对目标字符串的每个可能起始位置进行了遍历匹配,找到第一个匹配项的下标。

9. 扩展

我们还可以探讨一些优化方案,如使用更高效的字符串匹配算法(例如 KMP 算法)来提高匹配的效率,或者讨论 Java 中字符串匹配方法的内部实现原理等。

希望本文能够帮助读者更好地理解字符串匹配问题及其解决方法。


这篇博客按照目录结构组织了问题描述、解题思路、代码实现和复杂度分析等内容,希望对您有所帮助!

相关文章
|
Go 索引
【LeetCode 热题100】394:字符串解码(详细解析)(Go语言版)
本文详细解析了 LeetCode 热题 394:字符串解码。题目要求对编码字符串如 `k[encoded_string]` 进行解码,其中 `encoded_string` 需重复 `k` 次。文章提供了两种解法:使用栈模拟和递归 DFS,并附有 Go 语言实现代码。栈解法通过数字栈与字符串栈记录状态,适合迭代;递归解法则利用函数调用处理嵌套结构,代码更简洁。两者时间复杂度均为 O(n),但递归需注意栈深度问题。文章还总结了解题注意事项及适用场景,帮助读者更好地掌握字符串嵌套解析技巧。
395 6
|
存储 机器学习/深度学习 缓存
🚀 力扣热题 394:字符串解码(详细解析)(Go语言版)
文章提供了两种解法:栈结构和递归解法。栈解法通过维护数字栈与字符串栈,依次处理 `[` 和 `]`,构造解码结果;递归解法则利用函数调用逐层解析嵌套结构。两者时间复杂度均为 $O(n)$,空间复杂度也为 $O(n)$。栈解法直观易懂,适合初学者;递归解法优雅简洁,适合处理深度嵌套规则。掌握这两种方法,可灵活应对类似问题,提升解题能力。
503 11
|
C++
Leetcode第43题(字符串相乘)
本篇介绍了一种用C++实现的字符串表示的非负整数相乘的方法,通过逆向编号字符串,将乘法运算转化为二维数组的累加过程,最后处理进位并转换为字符串结果,解决了两个大数相乘的问题。
186 9
|
JavaScript
力扣3333.找到初始输入字符串Ⅱ
【10月更文挑战第9天】力扣3333.找到初始输入字符串Ⅱ
228 1
|
存储 算法
LeetCode第43题字符串相乘
LeetCode第43题"字符串相乘"的解题方法,通过使用数组存储乘积并处理进位,避免了字符串转换数字的复杂性,提高了算法效率。
LeetCode第43题字符串相乘
|
算法 C++
Leetcode第八题(字符串转换整数(atoi))
这篇文章介绍了LeetCode上第8题“字符串转换整数(atoi)”的解题思路和C++的实现方法,包括处理前导空格、正负号、连续数字字符以及整数溢出的情况。
363 0
【LeetCode 22】459.重复的子字符串
【LeetCode 22】459.重复的子字符串
213 0
【LeetCode 20】151.反转字符串里的单词
【LeetCode 20】151.反转字符串里的单词
162 0
【LeetCode 19】541.反转字符串II
【LeetCode 19】541.反转字符串II
193 0
【LeetCode 18】6.2.反转字符串
【LeetCode 18】6.2.反转字符串
140 0

热门文章

最新文章