算法训练Day9| LeetCode28. 找出字符串中第一个匹配项的下标(KMP算法)
28. 找出字符串中第一个匹配项的下标
给你两个字符串 haystack
和 needle
,请你在 haystack
字符串中找出 needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle
不是 haystack
的一部分,则返回 -1
。
class Solution { public int strStr(String haystack, String needle) { if (haystack.isEmpty()) return 0; int n = haystack.length(); int m = needle.length(); haystack = " " + haystack; needle = " " + needle; char[] s = haystack.toCharArray(); char[] p = needle.toCharArray(); int[] next = new int[m + 1]; for (int i = 2, j = 0; i <= m; i++) { while (j > 0 && p[i] != p[j + 1]) j = next[j]; if (p[i] == p[j + 1]) j++; next[i] = j; } for (int i = 1, j = 0; i <= n; i++) { while (j > 0 && s[i] != p[j +1]) j = next[j]; if (s[i] == p[j + 1]) j++; if (j == m) return i - m; } return -1; } }
459. 重复的子字符串
给定一个非空的字符串 s
,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。
class Solution { public boolean repeatedSubstringPattern(String s) { return kmp(s); } private boolean kmp(String pattern) { int n = pattern.length(); int[] fail = new int[n]; Arrays.fill(fail, -1); for (int i = 1; i < n; i++) { int j = fail[i - 1]; while (j != -1 && pattern.charAt(j + 1) != pattern.charAt(i)) { j = fail[j]; } if (pattern.charAt(j + 1) == pattern.charAt(i)) { fail[i] = j + 1; } } return fail[n - 1] != -1 && n % (n - fail[n - 1] - 1) == 0; } }