*[Lintcode]strStr

本文介绍了两种经典的字符串匹配算法——KMP算法与哈希值算法。KMP算法避免了传统匹配中重复子串的比对过程,提高了搜索效率;哈希值算法通过计算字符串的哈希值来快速判断两字符串是否相等,适用于字母种类较少的情况。
摘要由CSDN通过智能技术生成

For a given source string and a target string, you should output thefirst index(from 0) of target string in source string.

If target does not exist in source, just return -1.

此题经典解法为KMP,但是面试时不一定给出KMP解法。除了KMP以外,还有哈希解法和标准解法。

下面是平方级复杂度的标准解法。

class Solution {
    /**
     * Returns a index to the first occurrence of target in source,
     * or -1  if target is not part of source.
     * @param source string to be scanned.
     * @param target string containing the sequence of characters to match.
     */
    public int strStr(String source, String target) {
        int index = 0, pos = 0;
        if(source == null || target == null) return -1;
        if(source.length() == 0 && target.length() == 0) return 0;

        for(; index + pos < source.length(); index++) {
            for(; pos < target.length(); pos++) {
                if(source.charAt(index + pos) != target.charAt(pos)) {
                    pos = 0;
                    break;//restart
                }
            }
            if(pos == target.length()) return index;
        }
        return -1;
    }
}

另外一种算法是利用哈希值计算。考虑到字母数量,哈希值取到32即可保证没有冲突。

具体算法如下: abc = 'a' * 32*32 + 'b' * 32 + 'c'*1

两个字符串分别计算比较字符串长度的哈希值。如果不同的话,待比较字符串移位,更新哈希值。


class Solution {
    /**
     * Returns a index to the first occurrence of target in source,
     * or -1  if target is not part of source.
     * @param source string to be scanned.
     * @param target string containing the sequence of characters to match.
     */
    public int strStr(String source, String target) {

        if(source == null || target == null) return -1;
        if(source.length() == 0 && target.length() == 0) return 0;
        if(source.length() == 0 && target.length() != 0) return -1;
        if(target.length() == 0) return 0;
        
        int n = target.length();

        int[] base = new int[n];
        base[0] = 1;
        for(int i = 1; i < n; i++)  {
            base[i] = base[i-1] * 32;
        }
        
        int tar = 0;
        int sou = 0;
        
        for(int i = 0; i < n; i++) {//
            tar += target.charAt(i) * base[n - 1 - i];
            sou += source.charAt(i) * base[n - 1 - i];
        }
        
        if(sou == tar) return 0;
        
        for(int i = target.length(); i < source.length(); i++) {
            sou = (sou - source.charAt(i - n) * base[n - 1]) * 32 + source.charAt(i);
            if(sou == tar) return i - n + 1;
        }
        return -1;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值