力扣经典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 中字符串匹配方法的内部实现原理等。
希望本文能够帮助读者更好地理解字符串匹配问题及其解决方法。
这篇博客按照目录结构组织了问题描述、解题思路、代码实现和复杂度分析等内容,希望对您有所帮助!