This article is a note taken when writing questions with the code Capriccio every day, which is used to summarize and review.
catalogue
Sword finger offer 05 Replace spaces
151. Reverse the words in the string
Sword finger offer 58 - Ⅱ Left rotation string
344. Reverse string
Title Link: 344. Reverse string - LeetCode (LeetCode CN. Com)
Idea: the idea is very simple, that is, a double pointer plus element exchange
public void reverseString(char[] s) { int left = 0; int right = s.length - 1; while (left < right){ char temp = s[left]; s[left++] = s[right]; s[right--] = temp; } }
541. Reverse string II
Title Link: 541. Reverse string II - LeetCode (LeetCode CN. Com)
Idea: invert the string of 0 + (2 * k) * i ~ (k - 1) + (2 * k) * i subscript within the string length range, and the value of i is 0, 1, 2, 3, Note that you can judge the case that the length exceeds the string length.
public String reverseStr(String s, int k) { char[] chars = s.toCharArray(); int left = 0; int right = left + k - 1; if (right >= chars.length){ right = chars.length - 1; } while (right < chars.length){ int fLeft = left; int fRight = right; while (fLeft < fRight){ char temp = chars[fLeft]; chars[fLeft++] = chars[fRight]; chars[fRight--] = temp; } left += 2 * k; right += 2 * k; if (left >= chars.length){ break; } if (right >= chars.length){ right = chars.length - 1; } } return new String(chars); }
Sword finger offer 05 Replace spaces
Title Link: Sword finger Offer 05 Replace space - LeetCode (LeetCode CN. Com)
Idea:
① : directly use the replace method in String
public String replaceSpace(String s) { String s1 = s.replace(" ", "%20"); return s1; }
② : do not use the solution of library function, use StringBuilder to splice strings to improve the speed
public String replaceSpace(String s) { StringBuilder str = new StringBuilder(); for(int i = 0 ; i < s.length(); i++){ char ch = s.charAt(i); if(ch == ' '){ str.append("%20"); } else{ str.append(ch); } } return str.toString(); }
③ : normal solution: first expand the length of the String to the length after replacement. Here, use StringBuilder to expand it, because String is immutable. Set two pointers, one to the end of the String before expansion (bf) and the other to the end of the String after expansion (af). Use bf to traverse the String from front to back. If spaces are found, use af to store "% 20". If no spaces are found, use af to store bf corresponding characters
public String replaceSpace(String s){ int count = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == ' '){ count++; } } StringBuilder stringBuilder = new StringBuilder(s); for (int i = 0; i < count; i++) { stringBuilder.append(" "); } String str = stringBuilder.toString(); char[] chars = str.toCharArray(); int bf = s.length() - 1; int af = stringBuilder.length() - 1; while (bf >= 0){ if (chars[bf] == ' '){ chars[af--] = '0'; chars[af--] = '2'; chars[af--] = '%'; bf--; }else { chars[af--] = chars[bf--]; } } return new String(chars); }
151. Reverse the words in the string
Title Link: 151. Flip the word in the string - LeetCode (LeetCode CN. Com)
Idea:
① : use the split function in String to get each word and splice the words
public String reverseWords(String s) { String[] s1 = s.split(" "); StringBuilder str = new StringBuilder(); int flag = 0; while (s1[flag].equals("")){ flag++; } for (int i = s1.length - 1; i > flag; i--) { if (!s1[i].equals("")){ str.append(s1[i]); str.append(" "); } } str.append(s1[flag]); return str.toString(); }
② : do not use library functions: first remove the spaces at the beginning and end of the string, then reverse the string and deal with the middle spaces, as follows
Original string:
Processed string:
Finally, use the space as a sign to get each word, and then reverse each word
public String reverseWords(String s) { char[] chars = s.toCharArray(); int left = 0; int right = chars.length - 1; StringBuilder newStr = new StringBuilder(); //Remove leading and trailing spaces while (left <= right){ if (chars[left] == ' '){ left++; } if (chars[right] == ' '){ right--; } if (chars[left] != ' ' && chars[right] != ' '){ break; } } //Reverse the string order and handle the middle space int bfRight = right - 1; while (right > left){ if (chars[right] != ' ' || (chars[right] == ' ' && chars[bfRight] != ' ')){ newStr.append(chars[right]); } right--; bfRight--; } newStr.append(chars[left]); getAndReverse(newStr); return newStr.toString(); } //Get each word and reverse it public void getAndReverse(StringBuilder stringBuilder){ int head = 0; int end = 0; while (end < stringBuilder.length()){ if (stringBuilder.charAt(end) == ' '){ reverse(stringBuilder, head, end - 1); head = end + 1; } end++; } reverse(stringBuilder, head, end - 1); } //Invert each word public void reverse(StringBuilder stringBuilder, int head, int end){ while (head < end){ char temp = stringBuilder.charAt(head); stringBuilder.setCharAt(head, stringBuilder.charAt(end)); stringBuilder.setCharAt(end, temp); head++; end--; } }
Sword finger offer 58 - Ⅱ Left rotation string
Title Link: Sword finger Offer 58 - II Left rotation string - LeetCode (LeetCode CN. Com)
Idea:
① : intercept the corresponding substring for splicing
public String reverseLeftWords(String s, int n){ StringBuilder ansStr = new StringBuilder(); ansStr.append(s.substring(n, s.length())); ansStr.append(s.substring(0, n)); return ansStr.toString(); }
② : invert the whole string first, and then the corresponding substring
public String reverseLeftWords(String s, int n){ StringBuilder ansStr = new StringBuilder(s); int length = ansStr.length(); reverse(ansStr, 0, length - 1); reverse(ansStr, 0, length - n - 1); reverse(ansStr, length - n, length - 1); return ansStr.toString(); } public void reverse(StringBuilder stringBuilder, int head, int end){ while (head < end){ char temp = stringBuilder.charAt(head); stringBuilder.setCharAt(head, stringBuilder.charAt(end)); stringBuilder.setCharAt(end, temp); head++; end--; } }
28. Implement str ()
Title Link: 28. Implement strStr() - LeetCode (LeetCode CN. Com)
Idea:
① : Horspool algorithm: set a move table. The setting rules are shown in the figure below. Move it against the move table according to the different conditions of the character c corresponding to the end of the haystack string and the need string when the matching is unsuccessful.
public int strStr(String haystack, String needle) { if (needle.length() == 0){ return 0; } Map<Character, Integer> move = new HashMap<>(); int flag = needle.length() - 1; int count = 0; if (needle.length() > 1){ while (flag > 0){ flag--; count++; if (!move.containsKey(needle.charAt(flag))){ move.put(needle.charAt(flag), count); } } } int hayPo = needle.length() - 1; while (hayPo < haystack.length()){ int nePo = needle.length() - 1; int moveHayPo = hayPo; while (needle.charAt(nePo) == haystack.charAt(moveHayPo)){ nePo--; moveHayPo--; if (nePo < 0){ return moveHayPo + 1; } } if (move.containsKey(haystack.charAt(hayPo))){ hayPo += move.get(haystack.charAt(hayPo)); }else { hayPo += needle.length(); } } return -1; }
② : KMP algorithm: directly learn Kago's video:
Help you learn the KMP algorithm thoroughly! (Theory) bilibili bili
Help you learn the KMP algorithm thoroughly! (seeking the code of next array) bilibili bili
public int strStr(String haystack, String needle) { if (needle.length() == 0){ return 0; } int[] next = new int[needle.length()]; next[0] = 0; int j = 0; for (int i = 1; i < needle.length(); i++){ while (j > 0 && needle.charAt(j) != needle.charAt(i)){ j = next[j - 1]; } if (needle.charAt(j) == needle.charAt(i)){ j++; } next[i] = j; } int needPo = 0; for (int i = 0; i < haystack.length(); i++) { while (needPo > 0 && needle.charAt(needPo) != haystack.charAt(i)) needPo = next[needPo - 1]; if (needle.charAt(needPo) == haystack.charAt(i)) needPo++; if (needPo == needle.length()) return i - needle.length() + 1; } return -1; }
459. Duplicate substring
Title Link: 459. Repeated substring - LeetCode (LeetCode CN. Com)
Idea: kmp algorithm is also used. By analyzing the next array, it can be found that if the length of the string can be divided by subtracting the longest common prefix from the length of the string, it means that the string conforms to the meaning of the question (of course, it depends on the solution of the question) 😭😭😭)
public boolean repeatedSubstringPattern(String s) { int length = s.length(); if (s.equals("")){ return false; } int[] next = new int[length]; next[0] = 0; int j = 0; for (int i = 1; i < length; i++) { while (j > 0 && s.charAt(j) != s.charAt(i)){ j = next[j - 1]; } if (s.charAt(i) == s.charAt(j)){ j++; } next[i] = j; } if (next[length - 1] > 0 && length % (length - next[length - 1]) == 0){ return true; } return false; }
Today's summary
The difficulty is the kmp algorithm, which needs to be understood more