【力扣算法20】之 8. 找出字符串中第一个匹配项的下标 (python方向)

简介: 【力扣算法20】之 8. 找出字符串中第一个匹配项的下标 (python方向)

问题描述


给你两个字符串 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 仅由小写英文字符组成

思路分析

在解决这个问题时,可以采用双指针的思路。首先,我们将两个指针分别指向 haystackneedle 的起始位置。然后,我们开始遍历 haystack 字符串,比较当前指针位置处的字符是否与 needle 字符串中的字符相同。如果相同,我们就继续比较下一个字符,直到完全匹配或者遍历完了 needle 字符串。

步骤如下:

  1. needle 是空字符串,则返回下标 0。
  2. 计算 haystackneedle 的长度,分别记为 nm
  3. haystack 的第一个字符开始遍历,遍历范围为 n - m + 1
  4. 对于每个位置 i,使用指针 j 遍历 needle ,并比较 haystack[i+j]needle[j] 的字符是否相等。如果相等,继续比较下一个字符;如果不相等,跳出循环。
  5. 如果 j 遍历到了 needle 的末尾,即 j == m,说明找到了第一个匹配项,返回当前指针 i 的值减去 needle 的长度 m
  6. 如果遍历完了 haystack 还没有找到匹配项,则返回 -1,表示 needle 不是 haystack 的一部分。

这样,我们就可以找到字符串 needle 在字符串 haystack 中的第一个匹配项的下标。


代码分析


  1. 首先,检查特殊情况,如果 needle 是空字符串,则直接返回下标 0,因为空字符串是任意字符串的子串。
  2. 计算 haystackneedle 的长度,分别赋值给变量 nm。这样做是为了避免在循环中多次访问 len() 函数。
  3. 使用外层循环 for i in range(n - m + 1) 遍历 haystack 的每个可能的起始位置。注意,外层循环的范围是 n - m + 1,因为当剩余的字符数小于 needle 的长度时,自然无法匹配。
  4. 在内层循环 for j in range(m) 中,使用指针 j 遍历 needle 的每个字符,并与 haystack 中对应位置的字符进行比较。如果字符相等,则继续比较下一个字符;如果字符不相等,则退出内层循环。
  5. 如果内层循环正常结束,即 j 遍历到了 needle 的末尾,说明找到了第一个匹配项,可以返回当前指针 i 的值。
  6. 如果外层循环结束后还没有找到匹配项,则返回 -1,表示 needle 不是 haystack 的子串。

这种算法的思路是逐个比较字符,直到找到匹配项或遍历完整个 haystack。在最坏情况下(没有匹配项或者匹配项在最后一个起始位置),需要进行大约 (n - m + 1) * m 次字符比较操作。


完整代码


class Solution(object):
  def strStr(self, haystack, needle):
      if not needle:  # 特殊情况判断:needle为空字符串
          return 0
      n = len(haystack)  # haystack长度
      m = len(needle)  # needle长度
      for i in range(n - m + 1):  # 遍历haystack的每个起始位置
          for j in range(m):  # 遍历needle的每个字符
              if haystack[i+j] != needle[j]:  # 当前字符不匹配,跳出内层循环
                  break
          else:
              return i  # 内层循环正常结束,找到匹配项,返回当前指针i的值
      return -1  # 未找到匹配项,返回-1

详细分析


class Solution(object):
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        ""

这段代码定义了一个名为 Solution 的类,并在类中定义了一个名为 strStr 的方法。strStr 方法接受两个参数 haystackneedle,它们分别表示被搜索的字符串和待搜索的子字符串。方法的返回类型声明为 int

if not needle:
            return 0

这段代码首先检查特殊情况,即如果 needle 是空字符串,则直接返回 0。因为空字符串是任何字符串的子串。

n = len(haystack)
        m = len(needle)

这段代码使用 len() 函数获取字符串 haystackneedle 的长度,并将它们分别存储在变量 nm 中。这样做是为了避免在后续循环中多次调用 len() 函数,从而提高效率。

for i in range(n - m + 1):
            j = 0
            while j < m and haystack[i+j] == needle[j]:
                j += 1
            if j == m:
                return i

这段代码使用两个循环来实现字符串的匹配。外层循环使用 for 循环遍历 haystack 中每个可能的起始位置,范围是 n - m + 1。因为当剩余的字符数少于 needle 的长度时,无法进行匹配。

内层循环使用 while 循环,通过比较 haystack 中的字符和 needle 中的字符来进行匹配。循环条件为 j < m and haystack[i+j] == needle[j],表示当指针 j 小于 needle 的长度并且当前字符匹配时,继续循环。

如果内层循环正常结束,并且指针 j 的值等于 m,即遍历完了整个 needle,说明找到了匹配的子串,返回当前指针 i 的值。

return -1

如果外层循环结束后仍然没有找到匹配项,则说明 needle 不是 haystack 的子串,返回 -1。


运行效果截图


调用示例


solution = Solution()
haystack = "sadbutsad"
needle = "sad"
haystack1 = "leetcode"
needle1 = "leeto"
print(solution.strStr(haystack, needle))
print(solution.strStr(haystack1, needle1))

运行结果


完结


相关文章
|
5天前
|
索引 Python
Python中的字符串格式化:详解与应用
Python中的字符串格式化:详解与应用
13 0
|
5天前
|
Python
Python小技巧:一种字符串的排序方式
该文介绍了如何对包含数字的字符串列表进行特定排序。首先,示例了一个初始问题,使用Python内置的`sorted()`函数未能达到预期(按数字部分升序排序)。然后,文章提出通过自定义排序键`sort_key`来解决,利用正则表达式提取字符串尾部数字并进行排序。进一步,文章扩展到处理如&#39;nxxx_name_nxxx&#39;格式的字符串,通过给前缀和后缀数字赋予不同权重进行复合排序,展示了如何实现先按前缀、再按后缀排序的功能。提供的代码示例成功地完成了任务。
|
2天前
|
机器学习/深度学习 算法 TensorFlow
【图像识别】谷物识别系统Python+人工智能深度学习+TensorFlow+卷积算法网络模型+图像识别
谷物识别系统,本系统使用Python作为主要编程语言,通过TensorFlow搭建ResNet50卷积神经算法网络模型,通过对11种谷物图片数据集('大米', '小米', '燕麦', '玉米渣', '红豆', '绿豆', '花生仁', '荞麦', '黄豆', '黑米', '黑豆')进行训练,得到一个进度较高的H5格式的模型文件。然后使用Django框架搭建了一个Web网页端可视化操作界面。实现用户上传一张图片识别其名称。
17 0
【图像识别】谷物识别系统Python+人工智能深度学习+TensorFlow+卷积算法网络模型+图像识别
|
5天前
|
索引 Python
Python字符串的定义与操作详解
Python字符串的定义与操作详解
7 1
|
5天前
|
IDE 开发工具 开发者
Python函数说明文档:编写清晰易懂的文档字符串
Python函数说明文档:编写清晰易懂的文档字符串
7 1
|
5天前
|
机器学习/深度学习 移动开发 知识图谱
Python 字符串
Python 字符串
|
6天前
|
机器学习/深度学习 人工智能 算法
中草药识别系统Python+深度学习人工智能+TensorFlow+卷积神经网络算法模型
中草药识别系统Python+深度学习人工智能+TensorFlow+卷积神经网络算法模型
40 0
|
6天前
|
存储 索引 Python
 Python字符串
 Python字符串
18 0
|
9天前
|
索引
【力扣刷题】两数求和、移动零、相交链表、反转链表
【力扣刷题】两数求和、移动零、相交链表、反转链表
17 2
【力扣刷题】两数求和、移动零、相交链表、反转链表
|
9天前
|
算法
"刷题记录:哈希表+双指针 | leetcode-2465. 不同的平均值数目 "
该文段是一篇关于编程题目的解答,主要讨论如何找到数组中所有不同平均值的个数。作者首先使用排序和哈希集来解决,将数组转为列表排序后,通过双指针计算平均值并存入哈希集以去重。然后,作者发现可以优化方案,通过双指针在排序后的数组中直接计算两数之和,用哈希集记录不重复的和,从而避免实际计算平均值,提高了算法效率。最终代码展示了这两种方法。
17 0