首页 > 编程语言 >力扣面试经典算法150题:找出字符串中第一个匹配项的下标

力扣面试经典算法150题:找出字符串中第一个匹配项的下标

时间:2024-08-16 18:58:41浏览次数:10  
标签:150 下标 匹配 int needle 力扣 字符串 return haystack

找出字符串中第一个匹配项的下标

今天的题目是力扣面试经典150题中的数组的简单题: 找出字符串中第一个匹配项的下标

题目链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/?envType=study-plan-v2&envId=top-interview-150

题目描述

给定一个字符串 haystack 和一个字符串 needle,请找出 needle 在 haystack 中第一次出现的位置(下标)。如果 needle 不是 haystack 的一部分,则返回 -1。

  • 示例:
    • 输入:
      haystack = “hello”, needle = “ll”
    • 输出:
      2
    • 输入:
      haystack = “aaaaa”, needle = “bba”
    • 输出:
      -1

题目分析

题目要求我们在一个字符串 haystack 中找到另一个字符串 needle 第一次出现的位置。如果 needle 不是 haystack 的一部分,则返回 -1。

很明显,字符串needle是被包含在haystack中的一个子串,这意味着needle的字符在haystack中连续出现。

只需要第一次出现的位置则意味着我们需要的结果是needle中的字符第一次在haystack中连续出现时的第一个字符在haystack中的下标。

解题思路

分隔法

第一时间想到的办法:

  1. 判断haystack是否包含needle,不包含直接返回-1。
  2. 判断haystack是否以needle开头, 是的话返回0。
  3. 使用needle分割haystack,获取第一段的字符串长度返回即可。

整串匹配法

在分割法之后再思考想到的办法,使用整个子串去匹配:

  1. 获取两个字符串的长度。
  2. 以两者差值作为循环条件进行循环。
  3. 截取当前下标开始到子串长度的字符串与子串对比,一致则返回下标的值。
  4. 返回-1。

单字符匹配法:

在整串匹配法后想到的,不截取字符串,直接依次比较每个字符:

  1. 获取两个字符串的长度。
  2. 以两者差值作为循环条件进行循环
  3. 从 haystack 的第一个字符开始,逐个字符比较。
  4. 如果发现 haystack 中有一段子串与 needle 相同,则返回这段子串的起始位置。
  5. 如果遍历完整个 haystack 都没有找到匹配的子串,则返回 -1。

KMP 算法:

在上诉方法用完以后,尝试找到该类型题目的特殊算法:

  1. 构建 KMP 的 next 数组,然后根据 next 数组进行快速匹配。
  2. 如果找到匹配的子串,则返回起始位置;否则,返回 -1。

有点抽象,没完全想明白,这里就不贴了。。。

实际算法代码
下面是使用直接搜索法的 Java 实现:

public static void main(String[] args) {
        StrStr solution = new StrStr();

        // 示例数据
        String haystack = "hello";
        String needle = "ll";

        // 调用计算第一个匹配项下标的方法
        int index1 = solution.strStr1(haystack, needle);
        int index2 = solution.strStr2(haystack, needle);
        int index3 = solution.strStr3(haystack, needle);

        // 输出结果
        System.out.println("The index1 of the first occurrence is: " + index1);
        System.out.println("The index2 of the first occurrence is: " + index2);
        System.out.println("The index3 of the first occurrence is: " + index3);
    }

    /**
     * 查找字符串中第一个匹配项的下标: 分割法
     *
     * @param haystack 主字符串
     * @param needle   子字符串
     * @return 第一个匹配项的下标
     */
    public int strStr1(String haystack, String needle) {
        if (needle.isEmpty()) {
            return 0;
        }

        if (!haystack.contains(needle)) {
            return -1;
        }
        if (haystack.startsWith(needle)) {
            return 0;
        }
        String[] split = haystack.split(needle);
        if (split.length > 0) {
            return split[0].length();
        }
        return -1;
    }


    /**
     * 查找字符串中第一个匹配项的下标:整串匹配法
     *
     * @param haystack 主字符串
     * @param needle   子字符串
     * @return 第一个匹配项的下标
     */
    public int strStr2(String haystack, String needle) {
        if (needle.isEmpty()) {
            return 0;
        }

        int n = haystack.length();
        int m = needle.length();

        for (int i = 0; i <= n - m; i++) {
            if (needle.equals(haystack.substring(i, i + m))) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 查找字符串中第一个匹配项的下标:单字符匹配法
     *
     * @param haystack 主字符串
     * @param needle   子字符串
     * @return 第一个匹配项的下标
     */
    public int strStr3(String haystack, String needle) {
        if (needle.isEmpty()) {
            return 0;
        }

        int n = haystack.length();
        int m = needle.length();

        for (int i = 0; i <= n - m; i++) {
            boolean found = true;
            for (int j = 0; j < m; j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    found = false;
                    break;
                }
            }
            if (found) {
                return i;
            }
        }

        return -1;
    }

结果

同时调用三个方法,返回结果都符合预期:

在这里插入图片描述

我们分别提交到力扣:

在这里插入图片描述
通过肯定都是通过的,这里贴第三种方法的图,因为这个方法的相对最优。

以下是三种方法的提交结果:

  1. 分割法

在这里插入图片描述

  1. 整串匹配法

在这里插入图片描述

  1. 单字符匹配法

    在这里插入图片描述

三种方法最先能想到的容易程度以及理解难度正好按与算法的效果相反,难道这就是算法吗

在这里插入图片描述

总结

今天自己想了三种方法,特殊算法KMP有点抽象一下子还没想明白,有兴趣的自行学习,明天我再抽空理解一下。

另外数组简单难度的题目已经做完,下面开始上强度了。。。

加油!!!

标签:150,下标,匹配,int,needle,力扣,字符串,return,haystack
From: https://blog.csdn.net/weixin_48668564/article/details/141205746

相关文章

  • CF1503E 2-Coloring
    CF1503E2-Coloring题目大意略过。做法解析不会组合,使用了DP,但其实本质相同。我们假设所有的格子都是蓝色的,然后考虑将一些格子换成黄色的。我们考虑从每一行的两头开始将格子换成黄色,只要不把整一行都换成黄色的我们就可以保证每一行恰好有一段蓝色的格子。为了保证每一......
  • 11. 盛最多水的容器【 力扣(LeetCode) 】
    一、题目描述给定一个长度为n的整数数组height。有n条垂线,第i条线的两个端点是(i,0)和(i,height[i])。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。说明:你不能倾斜容器。二、测试用例示例1:输入:[1,......
  • 15. 三数之和【 力扣(LeetCode) 】
    一、题目描述给你一个整数数组nums,判断是否存在三元组[nums[i],nums[j],nums[k]]满足i!=j、i!=k且j!=k,同时还满足nums[i]+nums[j]+nums[k]==0。请你返回所有和为0且不重复的三元组。注意:答案中不可以包含重复的三元组。二、测试用例示例1:输......
  • 世微AP5125 外置MOS管5-150V 8A平均电流型LED降压恒流驱动器 SOT23-6 手电筒与车灯方
    产品描述AP5125是一款外围电路简单的Buck型平均电流检测模式的LED恒流驱动器,适用于8-100V电压范围的非隔离式大功率恒流LED驱动领域。芯片采用固定频率140kHz的PWM工作模式,利用平均电流检测模式,因此具有优异的负载调整率特性,高精度的输出电流特性。AP5125......
  • 【力扣高频题】021.括号生成
    上篇文章我们学习了判断一个字符串是否是有效的括号顺序:有效的括号。今天我们继续来学习一道有关有效括号的中等难度题目。22.括号生成数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。示例1:输入:n=3输出:[“((())......
  • 力扣 | 一维简单线性dp | 2140. 解决智力问题、322. 零钱兑换、2466. 统计构造好字符
    文章目录一、2140.解决智力问题二、322.零钱兑换三、2466.统计构造好字符串的方案数四、91.解码方法五、983.最低票价六、790.多米诺和托米诺平铺需要特别注意的题目有2140.解决智力问题和983.最低票价,因为这两个题目可以启发思路,其他的题都比较普通。一、21......
  • 力扣 | 动态规划 | 状态机 | 买卖股票 | 买卖股票的最佳时机
    文章目录一、309.买卖股票的最佳时机含冷冻期二、714.买卖股票的最佳时机含手续费三、123.买卖股票的最佳时机III四、188.买卖股票的最佳时机IV本质上这种属于动态规划题目但又有多种状态的,我们只需要正确定义出状态即可。可能每个人定义的状态不一样,但只要是对......
  • 力扣第五十九题——螺旋矩阵II
    内容介绍给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 nxn 正方形矩阵 matrix 。示例1:输入:n=3输出:[[1,2,3],[8,9,4],[7,6,5]]示例2:输入:n=1输出:[[1]]提示:1<=n<=20完整代码classSolution{publi......
  • 栈与计算—— 150、227、224※
    150.逆波兰表达式求值(中等)给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。注意:有效的算符为 '+'、'-'、'*' 和 '/' 。每个操作数(运算对象)都可以是一个整数或者另一个表达式。两个整数......
  • leetcode面试经典150题- 380. O(1) 时间插入、删除和获取随机元素
     https://leetcode.cn/problems/insert-delete-getrandom-o1/description/?envType=study-plan-v2&envId=top-interview-150gotypeRandomizedSetstruct{isHavemap[int]inttotalintarr[]int}funcConstructor()RandomizedSet{retur......