kmp算法

假设字符串str长度为N,字符串match长度为MM <= N

想确定str中是否有某个子串是等于match的。

时间复杂度O(N)

如果一个str,要确定match是否是他的子串,比如从0位置开始匹配,一直匹配,到match最后一位没有匹配到,那么我们就需要从str的1位置继续循环,这是暴力解法.KMP就是对回退做了一个优化.

假如我们的match字符串为 1231234 那么会生成一个next数组 

这个数组意思比如你到了match最后一个位置 这个位置值为3,3的含义就是123 123 一样,如果和str不匹配你可以回退到match[3]这个位置继续的str比较,不用回退到match[0]比较 因此时间复杂度才可以减少0n

public static int getIndexOf(String s1, String s2) {
		if (s1 == null || s2 == null || s2.length() < 1 || s1.length() < s2.length()) {
			return -1;
		}
		char[] str1 = s1.toCharArray();
		char[] str2 = s2.toCharArray();
		int x = 0;
		int y = 0;
		// O(M) m <= n
		int[] next = getNextArray(str2);
		// O(N)
		while (x < str1.length && y < str2.length) {
			if (str1[x] == str2[y]) {
				x++;
				y++;
			} else if (next[y] == -1) { // y == 0
				x++;
			} else {
				y = next[y];
			}
		}
		return y == str2.length ? x - y : -1;
	}

	public static int[] getNextArray(char[] str2) {
		if (str2.length == 1) {
			return new int[] { -1 };
		}
		int[] next = new int[str2.length];
		next[0] = -1;
		next[1] = 0;
		int i = 2; // 目前在哪个位置上求next数组的值
		int cn = 0; // 当前是哪个位置的值再和i-1位置的字符比较
		while (i < next.length) {
			if (str2[i - 1] == str2[cn]) { // 配成功的时候
				next[i++] = ++cn;
			} else if (cn > 0) {
				cn = next[cn];
			} else {
				next[i++] = 0;
			}
		}
		return next;
	}

KMP算法变化题

给定两棵二叉树的头节点head1head2

想知道head1中是否有某个子树的结构和head2完全一样

思路: 树直接先序或者后序遍历,然后再KMP就行

判断str1str2是否是旋转字符串

思路:旋转就是说  1234 他的旋转就是 1234 2341  3412  4123   那么我可以把str1+str1  然后看这个新的和str2做KMP    即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

普朗克的朗姆酒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值