代码随想录算法训练营第九天|28.找出字符串中第一个匹配的下标

代码随想录算法训练营第九天|28.找出字符串中第一个匹配的下标

一. 字符串相关算法题

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

暴力双指针

思路
  1. 定义两个指针i,j分别指向两个字符串的起始位置,如果相等继续对比如果不等i从上次指针起始位置加1为起始点开始对比
  2. 直至j等于needle最后一个也相等返回或者i指向最后一个都没有找到全相等的返回-1;
构建next数组思路
  1. 定义i,j双指针:i指向后缀末尾,j指向前缀末尾
  2. 前后缀不相等处理:j回退到前缀数组上一位指向的下标
  3. 前后缀相等处理: j++,
  4. 每轮for循环:nex[i] = j;
  • 时间复杂度:O(nm)
  • 空间复杂度O(1)
class Solution {
    public int strStr(String haystack, String needle) {
        if (haystack.length()<needle.length()){ //剪枝
            return -1;
        }
        int i = 0; //haystack指针
        int lastIStart = i; //上一个haystack指针起始指针位置
        int j = 0; //needle指针
        while (j<needle.length()&&i<haystack.length()){  //循环终止条件:needle字符都匹配或者haystack中找不到匹配的
            if (haystack.charAt(i)==needle.charAt(j)){
                if (j==needle.length()-1){ //如果相等的话且一直相等到needle结束,当前循环i的起始位置就是返回值
                    return lastIStart;
                }
//                System.out.println("=="+i+"->"+j+"->"+start);
                j++;
                i++;
            }else {
                j=0; //needle指针从头开始对比
                i=lastIStart+1; 
                lastIStart = i;
//                System.out.println("!="+i+"->"+j+"->"+start);
            }

        }
        return -1;
    }
}

kmp

  1. 求出每个子串的最长相等前后缀存入next数组中然后通过next数组回溯向下查找
  2. 可以避免上面暴力解法每次都要从头查找
  • 时间复杂度O(n+m) :next数组O(m) + for循环查找: O(n)
  • 空间复杂度 O(m)
class Solution {
    public int strStr(String haystack, String needle) {
        if (haystack.length()<needle.length()){ //剪枝
            return -1;
        }

        int[] next = new int[needle.length()];
        getNext(next,needle); //前缀数组
//        System.out.println(Arrays.toString(next));
        int j = 0; //needle指针
        for (int i = 0; i < haystack.length(); i++) {
            while (j>0 && needle.charAt(j) != haystack.charAt(i)){
                j = next[j-1]; //不相等j向前回退
            }
            if (needle.charAt(j) == haystack.charAt(i)){
                j++; //相等双指针前移:i在for循环中移动
            }
            if (j == needle.length()){  //移动到模式串末尾证明找到匹配子串了
                return i-needle.length()+1; //计算第一个匹配字符所在位置
            }
        }
        return -1;
    }

    private void getNext(int[] next, String s){
        int j = 0;
        next[0] = 0;
        for (int i = 1; i < s.length(); i++) { //注意i从1开始
            //前后缀不相等一直往前找
            while (j>0 && s.charAt(i) != s.charAt(j)){
                j = next[j-1]; //向前回退
            }
            //前后缀相等j往后移动
            if (s.charAt(j) == s.charAt(i)){
                j++;
            }
            next[i] = j;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二天的算法训练营主要涵盖了Leetcode题目的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组找到长度最小的子数组,

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值