代码随想录算法训练营Day8 | 剑指Offer 58-II.左旋转字符串 28. 实现 strStr() 459.重复的子字符串
剑指Offer 58-II.左旋转字符串 题目链接
列表遍历拼接,也可以使用String,方法一样
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder res = new StringBuilder();
for(int i = n ; i < s.length();i++ ){
res.append(s.charAt(i));
}
for(int i = 0 ; i < n ; i++){
res.append(s.charAt(i));
}
return res.toString();
}
}
28. 实现 strStr()题目链接
朴素解法
没有使用kmp,推测needle含有haystack的子字符串,减去重复的,然后从头开始遍历两个数组是否
存在重复子字符串,如果b直接到m就说明遍历结束。
class Solution {
public int strStr(String haystack, String needle) {
int n = haystack.length(), m = needle.length();
char[] hay = haystack.toCharArray(), need = needle.toCharArray();
for(int i = 0 ; i <= n - m ; i++){
int a = i , b = 0;
while(b < m && hay[a] == need[b]){
a++;b++;
}
if(b == m) return i;
}
return -1;
}
}
kmp解法
- 初始化数据(我习惯在开头加空白格
- 利用快慢指针遍历(制作next数组
- 循环当needle[i]不等于needle[j + 1], j赋值next[j]
- 如果needle[i] 等于 needle[j + 1] 则j++;
- next[i] = j;
- 通过next数组解决题目
class Solution {
public int strStr(String haystack, String needle) {
if(needle.length == 0)return false;
int lena = haystack.length(), lenb = needle.length();
haystack = " " +haystack;
needle = " " + needle;
char[] h = haystack.toCharArray();
char[] d = needle.toCharArray();
int[] next = new int[lenb + 1];
for(int i = 2 , j = 0 ; i <= lenb ; i++){
while(j > 0 && d[i] != d[j + 1])j = next[j];
if(d[i] == d[j + 1])j++;
next[i] = j;
}
//i 从 1开始 是因为h[0]=" "
for(int i = 1 , j = 0 ; i <= lena ; i++){
while(j > 0 && h[i] != d[j + 1])j = next[j];
if(h[i] == d[j+1])j++; //两个字符串相等 j++;
if(j == lenb) return i - lenb;
}
return -1;
}
}
459.重复的子字符串题目链接
class Solution {
public boolean repeatedSubstringPattern(String s) {
if(s.equals("")) return false;
int len = s.length();
//初始化
s = " " + s;
char [] ss = s.toCharArray();
int [] next = new int[len + 1];
for(int i = 2, j = 0 ; i <= len; i++){
while(j > 0 && ss[j + 1] != ss[i])j = next[j];
if(ss[i] == ss[j + 1])j++;
next[i] = j;
}
if(next[len] > 0 && len %(len - next[len])==0) return true;
return false;
}
}
如果s存在重复子字符串,则next[len]肯定找到前序重复的,所有>0,
如果len % (len - (next[len - 1] + 1)) == 0 ,则说明数组的长度正好可以被 (数组长度-最长相等前后缀的长度) 整除 ,说明该字符串有重复的子字符串。