代码随想录
LeetCode 题解
字符串匹配 Rabin-Karp 算法
字符串匹配 KMP 算法
1、反转字符串
344 - 反转字符串
| public void reverseString(char[] s) { |
| int p1 = 0; |
| int p2 = s.length - 1; |
| |
| char temp; |
| while (p1 < p2) { |
| temp = s[p1]; |
| s[p1] = s[p2]; |
| s[p2] = temp; |
| p1++; |
| p2--; |
| } |
| } |
2、反转字符串 II
541 - 反转字符串 II
| public String reverseStr(String s, int k) { |
| int n = s.length(); |
| char[] arr = s.toCharArray(); |
| |
| |
| for (int i = 0; i < n; i += 2 * k) { |
| reverse(arr, i, Math.min(n - 1, i + k - 1)); |
| } |
| |
| return new String(arr); |
| } |
| |
| |
| |
| |
| public void reverse(char[] arr, int p1, int p2) { |
| char temp; |
| while (p1 < p2) { |
| temp = arr[p1]; |
| arr[p1] = arr[p2]; |
| arr[p2] = temp; |
| p1++; |
| p2--; |
| } |
| } |
| public String reverseStr(String s, int k) { |
| char[] arr = s.toCharArray(); |
| reverseStr(arr, 0, k); |
| return new String(arr); |
| } |
| |
| |
| |
| |
| private void reverseStr(char[] arr, int l, int k) { |
| if (l >= arr.length - 1) return; |
| |
| |
| int p1 = l; |
| int p2 = Math.min(arr.length - 1, l + k - 1); |
| |
| char temp; |
| while (p1 < p2) { |
| temp = arr[p1]; |
| arr[p1] = arr[p2]; |
| arr[p2] = temp; |
| p1++; |
| p2--; |
| } |
| |
| reverseStr(arr, l + 2 * k, k); |
| } |
3、替换空格
剑指 Offer 05 - 替换空格
| public String replaceSpace(String s) { |
| StringBuilder sb = new StringBuilder(); |
| for (char c : s.toCharArray()) { |
| if (c == '.') sb.append(' '); |
| else sb.append(c); |
| } |
| return sb.toString(); |
| } |
4、反转字符串中的单词
151 - 反转字符串中的单词
| public String reverseWords(String s) { |
| String[] arr = s.trim().split(" "); |
| StringBuilder sb = new StringBuilder(); |
| |
| for (int i = arr.length - 1; i >= 0; i--) { |
| String word = arr[i]; |
| |
| if (word.equals("")) continue; |
| |
| sb.append(word); |
| if (i != 0) sb.append(" "); |
| } |
| |
| return sb.toString(); |
| } |
5、左旋转字符串
剑指 Offer 58 - II - 左旋转字符串
| public String reverseLeftWords(String s, int n) { |
| return s.substring(n) + s.substring(0, n); |
| } |
6、找出字符串中第一个匹配项的下标
28 - 找出字符串中第一个匹配项的下标
| public int strStr(String s, String t) { |
| if (t.length() == 0) return 0; |
| if (s.length() < t.length()) return -1; |
| |
| int[] lps = getLPS(t); |
| |
| int si = 0; |
| int ti = 0; |
| while (si < s.length()) { |
| if (s.charAt(si) == t.charAt(ti)) { |
| si++; |
| ti++; |
| if (ti == t.length()) return si - t.length(); |
| } |
| else if (ti > 0) ti = lps[ti - 1]; |
| else si++; |
| } |
| |
| return -1; |
| } |
| |
| private int[] getLPS(String t) { |
| |
| int[] lps = new int[t.length()]; |
| |
| for (int i = 1; i < lps.length; i++) { |
| int a = lps[i - 1]; |
| while (a > 0 && t.charAt(a) != t.charAt(i)) a = lps[a - 1]; |
| if (t.charAt(a) == t.charAt(i)) lps[i] = a + 1; |
| } |
| |
| return lps; |
| } |
7、重复的子字符串
459 - 重复的子字符串
| 如果字符串 str 可以由它的一个子串重复多次构成 |
| str = s + s |
| str + str = [s + s] + [s + s] = s + [s + s] + s |
| |
| 如果字符串 str 不可以由它的一个子串重复多次构成 |
| str = s1 + s2 |
| str + str = [s1 + s2] + [s1 + s2] = s1 + [s2 + s1] + s2 != s1 + [s1 + s2] + s2 |
| public boolean repeatedSubstringPattern(String s) { |
| String str = s + s; |
| return str.substring(1, str.length() - 1).contains(s); |
| } |
| public boolean repeatedSubstringPattern(String s) { |
| int n = s.length(); |
| int[] lps = getLPS(s); |
| |
| return lps[n - 1] != 0 && n % (n - lps[n - 1]) == 0; |
| } |
| |
| private int[] getLPS(String t) { |
| |
| int[] lps = new int[t.length()]; |
| |
| for (int i = 1; i < lps.length; i++) { |
| int a = lps[i - 1]; |
| while (a > 0 && t.charAt(a) != t.charAt(i)) a = lps[a - 1]; |
| if (t.charAt(a) == t.charAt(i)) lps[i] = a + 1; |
| } |
| |
| return lps; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步