题目链接:344.反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s
的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
解题思路:看到这道题目没啥好说的,直接一个双指针交换搞定
class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
// 临时变量,暂存字符
char temp;
// 直到左右指针相遇
while(left < right){
// 暂存左指针字符
temp = s[left];
s[left++] = s[right];
s[right--] = temp;
}
}
}
题目链接:541.反转字符串II
给定一个字符串 s
和一个整数 k
,从字符串开头算起,每计数至 2k
个字符,就反转这 2k
字符中的前 k
个字符。
- 如果剩余字符少于
k
个,则将剩余字符全部反转。 - 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。
解题思路:看到这道题目一脸懵逼没看懂啥意思,搞了半天才明白是:从头开始,第0到k个反转 k+1 到2k正常,2k+1到3k反转。。。所以解法就很明确了循环一遍字符串,每隔2k个反转前k个,尾数不够k个时全部反转。直接用下标法或者转为数组再for循环都行。
class Solution {
public String reverseStr(String s, int k) {
char[] charArray = s.toCharArray();
for (int i = 0; i <= charArray.length - 1; i += 2 * k) {
int start = i;
int end = Math.min(charArray.length - 1, start + k - 1);
while (start < end) {
char temp = charArray[start];
charArray[start++] = charArray[end];
charArray[end--] = temp;
}
}
return String.valueOf(charArray);
}
}
易错点:靠又看错下标,第k个字符,下标是k-1。。。
题目链接:54.替换数字
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。
解题思路:看到这道题目的第一想法是直接循环一遍遇到数字直接替换成number。
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
// 判断是否为数字
if (Character.isDigit(s.charAt(i))) {
sb.append("number");
} else sb.append(s.charAt(i));
}
System.out.println(sb);
}
}
题目链接:151.反转字符串中的单词
给你一个字符串 s
,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s
中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串
解题思路:看到这道题目的第一想法和反转字符串类似,多了对空格的处理。主要分为三步:
1.去除字符串中多余的空格,并且每个单词间只有一个空格
2.将整个字符串进行反转
3.将每个单词进行反转
class Solution {
public String reverseWords(String s) {
s = s.trim();
// 去除空格
StringBuilder s1 = removeExtraSpaces(s);
// 反转字符串
reverseString(s1, 0, s1.length() - 1);
// 反转每个单词
reverseEachWord(s1);
return s1.toString();
}
private StringBuilder removeExtraSpaces(String s) {
int start = 0;
int end = s.length() - 1;
StringBuilder sb = new StringBuilder();
while (start <= end) {
char c = s.charAt(start);
// sb最后一位不为' '时添加' '
if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
sb.append(c);
}
start++;
}
return sb;
}
//对指定区间进行反转,左闭右闭
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--;
}
}
private void reverseEachWord(StringBuilder s) {
//起始下标
int start = 0;
int end = 1;
while (start < s.length()) {
while (end < s.length() && s.charAt(end) != ' ') {
end++;
}
reverseString(s, start, end - 1);
start = end + 1;
end = start + 1;
}
}
}
题目链接:55.右旋字符串
字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。
解题思路:看到这道题目的第一想法是直接反转三次即可。
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = Integer.parseInt(in.nextLine());
String s = in.nextLine();
StringBuilder sb = new StringBuilder(s);
reserveString(sb, 0, n - 1);
reserveString(sb, n, s.length() - 1);
reserveString(sb, 0, sb.length() - 1);
System.out.println(sb);
}
public static void reserveString(StringBuilder s, int start, int end) {
while (start < end) {
char temp = s.charAt(start);
s.setCharAt(start, s.charAt(end));
s.setCharAt(end, temp);
start++;
end--;
}
}
}