leecode更新
This commit is contained in:
parent
48fa58f8f2
commit
bb316cd55c
|
|
@ -0,0 +1,63 @@
|
|||
package com.markilue.leecode.string;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @BelongsProject: Leecode
|
||||
* @BelongsPackage: com.markilue.leecode.string
|
||||
* @Author: dingjiawen
|
||||
* @CreateTime: 2022-09-12 12:15
|
||||
* @Description: TODO 力扣459题:重复的子字符串:
|
||||
* 给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class RepeatedSubstringPattern {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String s = "abcabcabc";
|
||||
System.out.println(repeatedSubstringPattern(s));
|
||||
// int[] next1 = getNext1(s);
|
||||
// System.out.println(Arrays.toString(next1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 这一题也可以用经典的KMP算法进行解决,又KMP算法可知:如果string由重复子字符串组成,其next数组一定是前面全是-1,后面全是升序排列
|
||||
* 如"abcabcabc",其next数组为[-1, -1, -1, 0, 1, 2, 3, 4, 5],所以规律是最后一个数+1可以整除是-1的数
|
||||
* 速度击败74.63%,内存击败10.85%
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public boolean repeatedSubstringPattern(String s) {
|
||||
|
||||
int[] next1 = getNext1(s);
|
||||
|
||||
int length = next1.length;
|
||||
if (next1[length - 1] != -1 && length % (length - next1[length - 1] - 1) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int[] getNext1(String needle) {
|
||||
int[] next = new int[needle.length()];
|
||||
next[0] = -1;
|
||||
int k = -1;
|
||||
for (int i = 1; i < needle.length(); ++i) {
|
||||
while (k != -1 && needle.charAt(k + 1) != needle.charAt(i)) {
|
||||
k = next[k];
|
||||
}
|
||||
if (needle.charAt(k + 1) == needle.charAt(i)) {
|
||||
++k;
|
||||
}
|
||||
next[i] = k;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
package com.markilue.leecode.string;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @BelongsProject: Leecode
|
||||
* @BelongsPackage: com.markilue.leecode.string
|
||||
* @Author: dingjiawen
|
||||
* @CreateTime: 2022-09-12 09:01
|
||||
* @Description: TODO 力扣28题:实现strStr()
|
||||
* 实现strStr()函数。
|
||||
* 给你两个字符串haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
|
||||
* <p>
|
||||
* 说明:
|
||||
* 当needle是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
|
||||
* 对于本题而言,当needle是空字符串时我们应当返回 0 。这与 C 语言的strstr()以及 Java 的indexOf()定义相符。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class StrStr {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
String haystack = "hello";
|
||||
String needle = "ll";
|
||||
int i = strStr(haystack, needle);
|
||||
System.out.println(i);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
|
||||
String haystack = "aaaaa";
|
||||
String needle = "bba";
|
||||
int i = strStr(haystack, needle);
|
||||
System.out.println(i);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
|
||||
String haystack = "baabbbbababbbabab";
|
||||
String needle = "abbab";
|
||||
int i = strStr(haystack, needle);
|
||||
System.out.println(i);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
|
||||
String haystack = "ababaabbbbababbaabaaabaabbaaaabbabaabbbbbbabbaabbabbbabbbbbaaabaababbbaabbbabbbaabbbbaaabbababbabbbabaaabbaabbabababbbaaaaaaababbabaababaabbbbaaabbbabb";
|
||||
String needle = "abbabbbabaa";
|
||||
int i = strStr(haystack, needle);
|
||||
System.out.println(i);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4() {
|
||||
|
||||
String haystack = "ababac";
|
||||
// String needle = "abbabbbabaa";
|
||||
int[] next = getNext1(haystack);
|
||||
System.out.println(Arrays.toString(next));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 尝试使用KMP算法:维护一个next数组,存储needle的最小前缀和最小后缀匹配的长度,从而减少从头开始匹配的次数,从而将时间复杂度从O(n*m)降到O(n+m)
|
||||
* 具体内容参考代码随想录和数据结构与算法之美的讲解内容
|
||||
* 速度击败39.11%,内存击败91.79%
|
||||
*
|
||||
* @param haystack
|
||||
* @param needle
|
||||
* @return
|
||||
*/
|
||||
public int strStr(String haystack, String needle) {
|
||||
int[] next = getNext(needle);
|
||||
int j = 0;
|
||||
for (int i = 0; i < haystack.length(); ++i) {
|
||||
|
||||
while (j > 0 && haystack.charAt(i) != needle.charAt(j)) {
|
||||
j = next[j - 1] + 1;
|
||||
}
|
||||
|
||||
if (haystack.charAt(i) == needle.charAt(j)) {
|
||||
++j;
|
||||
}
|
||||
|
||||
if (j == needle.length()) {
|
||||
return i - j + 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public int[] getNext(String needle) {
|
||||
|
||||
int[] result = new int[needle.length()];
|
||||
|
||||
for (int i = 0; i < needle.length(); i++) {
|
||||
result[i] = -1;
|
||||
if (i == 0) {
|
||||
continue;
|
||||
}
|
||||
int right = i;
|
||||
for (int left = i - 1; left >= 0; left--) {
|
||||
boolean flag = false;
|
||||
if (needle.charAt(left) == needle.charAt(right)) {
|
||||
flag = true;
|
||||
for (int z = left - 1, k = right - 1; z >= 0; z--, k--) {
|
||||
if (needle.charAt(z) != needle.charAt(k)) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
result[i] = left;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 官方获取next数组的方法:精髓在于这次的next[i]可以通过上一次的next[i-1]来获取,分为两种情况:
|
||||
* 1)如果next[i-1]的下一个数和next[i]的下一个数相等,那么最大子串一定是在上一个的基础上+1,对应下面的if的内容
|
||||
* 2)如果next[i-1]的下一个数和next[i]的下一个数不相等,那么寻找上一个最大子串,看看上一次最大子串的下一个数和next[i]的下一个数相等,如果不相等就寻找在上一次的,对应于下面的while内容
|
||||
* 下所述的看就是用来记录上一次最大子串的索引
|
||||
*
|
||||
* 速度击败39.11%,内存击败73.88%
|
||||
* 但是只用了1ms
|
||||
* @param needle
|
||||
* @return
|
||||
*/
|
||||
public int[] getNext1(String needle) {
|
||||
int[] next = new int[needle.length()];
|
||||
next[0] = -1;
|
||||
int k = -1;
|
||||
for (int i = 1; i < needle.length(); ++i) {
|
||||
while (k != -1 && needle.charAt(k + 1) != needle.charAt(i)) {
|
||||
k = next[k];
|
||||
}
|
||||
if (needle.charAt(k + 1) == needle.charAt(i)) {
|
||||
++k;
|
||||
}
|
||||
next[i] = k;
|
||||
}
|
||||
|
||||
return next;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue