力扣爆刷第139天之字符串七连刷(翻转双指针)
文章目录
一、344. 反转字符串
题目链接:https://leetcode.cn/problems/reverse-string/description/
思路:双指针,头尾交换。
class Solution {
public void reverseString(char[] s) {
int i = 0, j = s.length-1;
while(i < j) {
char c = s[i];
s[i] = s[j];
s[j] = c;
i++;
j--;
}
}
}
二、541. 反转字符串 II
题目链接:https://leetcode.cn/problems/reverse-string-ii/description/
思路:两个k一组翻转字符串,先将前面完整的2k给处理掉,然后剩下的要判断,通过len - 2kn < k判断剩余之数不足1k,剩的全翻转,通过len - 2kn > k 剩余结果大于1K,则只翻转K个。
class Solution {
public String reverseStr(String s, int k) {
char[] list = s.toCharArray();
int t = 2 * k;
int num = list.length / t;
for (int i = 0; i < num; i++) {
swap(list, i * t, i * t + k - 1);
}
if (list.length - t * num < k) {
swap(list, t * num, list.length-1);
} else {
swap(list, t * num, t * num + k - 1);
}
return new String(list);
}
void swap(char[] list, int i, int j) {
while (i < j) {
char c = list[i];
list[i] = list[j];
list[j] = c;
i++;
j--;
}
}
}
三、54. 替换数字(第八期模拟笔试)
题目链接:https://kamacoder.com/problempage.php?pid=1064
思路:遍历替换即可,注意使用StringBuilder。
import java.util.*;
import java.lang.*;
class Main {
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
String s = scan.next();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(c >= '0' && c <= '9') {
sb.append("number");
}else{
sb.append(c);
}
}
System.out.println(sb.toString());
}
}
四、151. 反转字符串中的单词
题目链接:https://leetcode.cn/problems/reverse-words-in-a-string/description/
思路:翻转字符串也是经典例题了,需要先把每个单词翻转,之后再整体翻转,这里使用两个stringbuilder进行收集,其中一个用来收集单词,每收集一个单词后置空,可以用于跳过空格。
class Solution {
public String reverseWords(String s) {
StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();
char[] list = s.toCharArray();
for(int i = 0; i < list.length; i++) {
if(list[i] != ' ') {
s1.append(list[i]);
}else if(s1.length() != 0){
s2.append(s1.reverse()).append(' ');
s1 = new StringBuilder();
}
}
if(s.charAt(s.length()-1) == ' ') {
s2.deleteCharAt(s2.length()-1);
}else{
s2.append(s1.reverse());
}
s2.reverse();
return s2.toString();
}
}
五、55. 右旋字符串(第八期模拟笔试)
题目链接:https://kamacoder.com/problempage.php?pid=1065
思路:和上一题类型,本题要求右旋字符串,只需要把区间 [0, len-k-1] 和 [len-k, len-1]区间先各自翻转,然后再整体[0, len-1]翻转,即可实现右旋。
import java.util.*;
import java.lang.*;
class Main {
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
int k = scan.nextInt();
String s = scan.next();
char[] list = s.toCharArray();
reverse(list, 0, list.length - k - 1);
reverse(list, list.length - k, list.length-1);
reverse(list, 0, list.length-1);
System.out.println(new String(list));
}
public static void reverse(char[] list, int l, int r) {
while(l < r) {
char c = list[l];
list[l] = list[r];
list[r] = c;
l++;
r--;
}
}
}
六、28. 找出字符串中第一个匹配项的下标
题目链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/
思路:本题可以使用KMP,也可以直接双层for,只不过时间复杂度是O(N2)。
class Solution {
public int strStr(String haystack, String needle) {
int n = haystack.length(), m = needle.length();
char[] hlist = haystack.toCharArray(), nlist = needle.toCharArray();
for(int i = 0; i <= n - m; i++) {
int a = i, b = 0;
while(b < m && hlist[a] == nlist[b]) {
a++;
b++;
}
if(b == m) return i;
}
return -1;
}
}
七、459. 重复的子字符串
题目链接:https://leetcode.cn/problems/repeated-substring-pattern/description/
思路:求字符串能不能由子串拼接出来,可以使用KPM,算是变体。
class Solution {
public boolean repeatedSubstringPattern(String s) {
if(s.length() == 1) return false;
int len = s.length();
char[] list = s.toCharArray();
for(int i = 0; i < len/2; i++) {
int a = 0, b = i+1, t = i-a+1;
while(b + t <= len) {
if(!equals(list, a, i+1, b, b+t)) break;
b += t;
}
if(b == len) return true;
}
return false;
}
boolean equals(char[] list, int l1, int l2, int r1, int r2) {
while(l1 < r1) {
if(list[l1] != list[l2]) return false;
l1++;
l2++;
}
return true;
}
}