# leetcode -- string

### Topic overview

1. Reverse string
1. Reverse string II
1. Sword finger Offer 05 Replace spaces
1. Flip the words in the string
2. Sword finger Offer58-II Left rotation string
3. 28.Implement str ()
1. Duplicate substring

### Sub topic explanation

344 reverse string
If the key part of the problem can be solved directly with library functions, it is recommended not to use library functions

If the library function is only a small part of the problem-solving process, and you already know the internal implementation principle of the library function, you can consider using the library function.

```    public void reverseString(char[] s) {
int end = s.length - 1;
char tmp;
tmp = s[end];
end--;
}
}
```

541 reverse string ii

```class Solution {
public String reverseStr(String s, int k) {
char[] arr = s.toCharArray();
int len = s.length();
int last = 2 * k - 1;
while (last <= len - 1){
last += 2 * k;
}
int end = (len - 1 - head < k) ? len - 1 : head + k - 1;
return String.valueOf(arr);
}

public void reverse(int first, int end, char[] arr){
while (first < end){
char tmp = arr[first];
arr[first] = arr[end];
arr[end] = tmp;
first++;
end--;
}
}
}
```

Plan and then decide
Block first

• Enough 2k
Exchange function
• Not enough 2k
Less than k-exchange function
Greater than k, less than 2k - exchange function

Replace spaces with sword finger Offer5

```class Solution {
public String replaceSpace(String s) {
StringBuffer stb = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char point = s.charAt(i);
if (point == ' '){
stb.append("%20");
}else {
stb.append(point);
}
}
return stb.toString();
}
}
```

Here is another idea:
1. The original string space can be expanded to accommodate newly changed characters.
2. Locate the last character of the original string
3. Locate the last character of the new string
4. Comparison and replication

```public String replaceSpace(String s) {
if(s == null || s.length() == 0){
return s;
}
//Expand the space and double the number of spaces
StringBuilder str = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i) == ' '){
str.append("  ");
}
}
//If there is no space, return directly
if(str.length() == 0){
return s;
}
//Define two pointers with spaces
int left = s.length() - 1;//Left pointer: points to the last position of the original string
s += str.toString();
int right = s.length()-1;//Right pointer: points to the last position of the extended string
char[] chars = s.toCharArray();
while(left>=0){
if(chars[left] == ' '){
chars[right--] = '0';
chars[right--] = '2';
chars[right] = '%';
}else{
chars[right] = chars[left];
}
left--;
right--;
}
return new String(chars);
}
```

151. Flip the words in the string
Method 1: compare the water, use the split function in the string, additional O(N) space, and finally string them together. Note that remove the last space and when there are continuous separators, such as two spaces. After the segmentation, it is "" and judged with. equals()
Method 2: reverse all characters, and finally reverse the words. The final time complexity is O(1). Execute step by step, and remove redundant spaces at the beginning. Inverts all strings. Reverse the words.

```	//FA Yi
public static String reverseWords(String s) {
String[] s1 = s.split(" ");
StringBuffer stb = new StringBuffer();
for (int i = s1.length - 1; i >= 0; i--){
if (!s1[i].equals("")) {
stb.append(s1[i] + " ");
}
}
//Remove last space
return stb.toString().substring(0,stb.length() - 1);
}

public static void main(String[] args) {
System.out.println(reverseWords("We      are happy"));//happy are We
}
```
```//Method II
class Solution {
/**
* Not implemented using Java built-in methods
* <p>
* 1.Remove excess spaces at the beginning and end and in the middle
* 2.Inverts the entire string
* 3.Reverse each word
*/
public String reverseWords(String s) {
// System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]");
// 1. Remove the beginning, end and middle excess spaces
StringBuilder sb = removeSpace(s);
// 2. Invert the entire string
reverseString(sb, 0, sb.length() - 1);
// 3. Reverse each word
reverseEachWord(sb);
return sb.toString();
}

private StringBuilder removeSpace(String s) {
// System.out.println("ReverseWords.removeSpace() called with: s = [" + s + "]");
int start = 0;
int end = s.length() - 1;
while (s.charAt(start) == ' ') start++;
while (s.charAt(end) == ' ') end--;
StringBuilder sb = new StringBuilder();
while (start <= end) {
char c = s.charAt(start);
if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
sb.append(c);
}
start++;
}
// System.out.println("ReverseWords.removeSpace returned: sb = [" + sb + "]");
return sb;
}

/**
* Inverts the characters of the specified interval [start, end] of the string
*/
public void reverseString(StringBuilder sb, int start, int end) {
// System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]");
while (start < end) {
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
// System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]");
}

private void reverseEachWord(StringBuilder sb) {
int start = 0;
int end = 1;
int n = sb.length();
while (start < n) {
while (end < n && sb.charAt(end) != ' ') {
end++;
}
reverseString(sb, start, end - 1);
start = end + 1;
end = start + 1;
}
}
}
```

Sword finger Offer58-II. Left rotation string
Method 1: comparing water is to use substring
In fact, the time complexity of using substr and inversion is the same, both of which are O(n), but using substr applies for additional space, so the space complexity is O(n), and the space complexity of inversion method is O(1).
Method 2: you can directly use inversion without substring. An interesting idea is:

```//Method I:
public String reverseLeftWords(String s, int n) {
StringBuilder sb = new StringBuilder();
sb.append(s.substring(n)+s.substring(0,n));
return sb.toString();
}
//Method 2:
class Solution {
public String reverseLeftWords(String s, int n) {
int len=s.length();
StringBuilder sb=new StringBuilder(s);
reverseString(sb,0,n-1);
reverseString(sb,n,len-1);
return sb.reverse().toString();
}
public void reverseString(StringBuilder sb, int start, int end) {
while (start < end) {
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
}
}
```

28. Implement str ()
The violent solution must not work. Here is a good api, the KMP algorithm. It is very important. It is recommended to memorize it
KMP algorithm

```    public static int strStr(String haystack, String needle) {
if (needle.equals("")) return 0;//Each topic has different requirements and waits for the opportunity
if (haystack.length() == 0 || needle.length() == 0 || haystack.length() < needle.length()) return -1;
char[] str1 = haystack.toCharArray();
char[] str2 = needle.toCharArray();
//Create the next[i] array and store the length of the longest (prefix and suffix equal) before the ith character of str2. Note that the string itself is not included
int[] next = new int[str2.length];
next[0] = -1;
if (str2.length > 1){//Prevent str2 from having only one character
next[1] = 0;
}
int i = 2;
//The initial cn records the value of next[i- 1]. Since the initial value of i here is 2, next[i-1] = 0, so cn = 0;
int cn = 0;
while (i < str2.length){
if (str2[i - 1] == str2[cn]){
next[i++] = ++cn;
}else if (cn == 0){
next[i++] = 0;
}else {
cn = next[cn];
}
}
//Using next [] array to solve string matching problem
int t1 = 0; int t2 = 0;
while (t1 < str1.length && t2 < str2.length){
if (str1[t1] == str2[t2]){
t1++;
t2++;
}else if (t2 == 0){
t1++;
}else {
t2 = next[t2];
}
}
return t2 == str2.length ? t1 - t2 : -1;
}

public static void main(String[] args) {
String haystack = "abcdeabcfee";
String needle = "d";
System.out.println(strStr(haystack,needle));
}
```

29. Duplicate substrings
I really didn't know to use KMP algorithm at first, but because it depends on whether it is a repeated string, the array of next [] is absolutely regular. You can run several next [] arrays to see the following rules:

```public static boolean repeatedSubstringPattern(String s) {
if (s.length() < 2) return false;
//KMP algorithm can be used to think that there must be corresponding rules in the next [] array
char[] arr = s.toCharArray();
int n = s.length();
int[] next = new int[n + 1];
next[0] = -1;
next[1] = 0;
int i = 2;
int cn = 0;
while (i <= n){
if (arr[i - 1] == arr[cn]){
next[i++] = ++cn;
}else if (cn == 0){
next[i++] = 0;
}else {
cn = next[cn];
}
}
for (int h : next){
System.out.println(h);
}
if (next[n] != 0 && n % (n - (next[n])) == 0){
return true;
}
return false;
}

public static void main(String[] args) {
String haystack = "abcabcabc";
System.out.println(repeatedSubstringPattern(haystack));
}
```

### summary

1. It is suggested that if the key part of the problem can be solved directly with library functions, it is recommended not to use library functions. If the library function is only a small part of the problem-solving process, and you already know the internal implementation principle of the library function, you can consider using the library function.
2. Double pointer method is commonly used in arrays, linked lists and strings. For many array filling problems, you can first expand the array with the filled size in advance, and then operate from the back to the front
3. When you need a fixed rule to process strings paragraph by paragraph, you should think about making an article on the expression of the for loop. There is an idea: first overall inversion and then local inversion, first local inversion and then overall inversion
4. The main idea of KMP is that when there is a string mismatch, you can know part of the previously matched text content, and you can use this information to avoid matching from the beginning---- The most important algorithm in string

Posted on Tue, 23 Nov 2021 10:13:42 -0500 by Ollie Saunders