strStr2

这篇博客主要解析了LeetCode上的题目strStr2,包括题目描述、样例、代码实现以及易错点和常用解题技巧。在实现中,需注意处理Hash值小于0的情况,防止整数溢出,并正确处理字符移位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

strStr2

原文首发自heliuphy的博客

题目描述

实现时间复杂度为 O(n + m)的方法 strStr。 strStr 返回目标字符串在源字符串中第一次出现的第一个字符的位置. 目标字串的长度为 m , 源字串的长度为 n . 如果目标字串不在源字串中则返回 -1。

样例

输入:source = "abcdef", target = "bcd"
输出:1
解释:
字符串第一次出现的位置为1

代码

public class Solution {
    /*
     * @param source: A source string
     * @param target: A target string
     * @return: An integer as index
     */
    public int strStr2(String source, String target) {
        // write your code here
        if (source == null || target == null) {
            return -1;
        }
        
        int m = target.length();
        int n = source.length();
        
        if (m == 0 && source != null) {
            return 0;
        }
        
        int targetHash = 0;
        int mod = Integer.MAX_VALUE / 33;
        
        for (int i = 0; i < m; i++) {
            targetHash = (targetHash * 33 + target.charAt(i) - 'a') % mod;
            if (targetHash < 0) {
                targetHash += mod; // ---- (1)
            }
        }
        
        int power33 = 1;
        for (int i = 0; i < m - 1; i++) {
            power33 = power33 * 33 % mod; // ------ (2)
        }
        
        int sourceHash = 0;
        for (int i = 0; i < n; i++) { if (i >= m) { // ------ (3)
                sourceHash = (sourceHash - (source.charAt(i - m) - 'a') * power33) % mod;
            }
            
            sourceHash = (sourceHash * 33 + source.charAt(i) - 'a') % mod; // [1]
            
            if (sourceHash < 0) { sourceHash += mod; } if (i >= m - 1 && sourceHash == targetHash) {
                if (target.equals(source.substring(i - m + 1, i + 1))) {
                    return i - m + 1;
                }
            }
        }
        return -1;
    }
}

易错点归纳

  • 要记得处理 Hash 值 < 0 的情况;
  • power33 也要取 mod ,不然也会超出 int 的范围;
  • i 应该是即将加入的字母的索引,真正加入在代码 [1] 处。举例:假如 target 的长度为 3,那么在即将加入第 4 个字母的时候才需要删除第一个字母。

常用代码方法小结

对于形式

a m n + b m n − 1 + c m n − 2 + … + d am^{n}+bm^{n-1}+cm^{n-2}+\ldots +d amn+bmn1+cmn2++d

写代码时可以通过以下形式来避免使用pow()函数。

int value = 0;
for (int i = 0; i <= n; i++) {
    value = value * m + char[i];
}

原文首发自heliuphy的博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值