目录
题目一:反转字符串
题目描述:
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
思路分析: 简单的交换数值即可解决
解法一:数值交换
class Solution {
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;
left++;
right--;
}
}
}
解法二:位运算
class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while (left < right) {
s[left] ^= s[right];
s[right] ^= s[left];
s[left] ^= s[right];
left++;
right--;
}
}
}
题目二:反转字符串||
题目描述:
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
思路分析:关键在于找出需要进行反转的区间,再调用reverse()即可解决, 视频指路
class Solution {
public String reverseStr(String s, int k) {
int n = s.length();
char[] ch = s.toCharArray();
// 每次前进2k,但是只交换前k个字符
for (int i = 0; i < ch.length; i += 2 * k) {
reverse(ch, i, Math.min(i + k - 1, n - 1)); // 调用reverse()实现反转
}
return new String(ch);
}
private void reverse(char[] ch, int left, int right) {
while (left < right) {
char temp = ch[left];
ch[left] = ch[right];
ch[right] = temp;
left++;
right--;
}
}
}
题目三:替换空格
题目描述:请实现一个函数,把字符串
s
中的每个空格替换成"%20"
思路分析:不使用额外空间的话,考虑使用双指针解题,但要注意填充顺序是从后到前,至于为什么这么做?思路链接 里有讲。
解法一:双指针
class Solution {
public String replaceSpace(String s) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ') {
str.append(" "); // 尾部扩充空间,两倍空格
}
}
if(str.length() == 0) {
return s;
}
int left = s.length() - 1;
s += str.toString(); // 将扩充的空间加入s
int right = s.length() - 1;
char[] ch = s.toCharArray(); // 字符串长度不可变,将新的s作为数组进行操作
while (left >= 0) {
if (ch[left] == ' ') { // 左指针遇到空格时,右指针下标递减,依次填入“0”,“2”,“%”
ch[right--] = '0';
ch[right--] = '2';
ch[right] = '%';
} else {
ch[right] = ch[left];
}
left--;
right--;
}
return new String(ch);
}
}
解法二:使用额外空间
// 遍历添加,使用额外辅助空间
class Solution {
public String replaceSpace(String s) {
StringBuilder res = new StringBuilder();
for (Character c : s.toCharArray()) {
if (c == ' ') {
res.append("%20");
} else {
res.append(c);
}
}
return res.toString();
}
}
题目四:翻转字符串里的单词
题目描述:
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
思路分析:移除多余空格、将整个字符串反转、将每个单词反转。
涉及很多字符串的操作,细节一两句说不清,建议直接看carl哥的视频讲解
解法一:
class Solution {
public String reverseWords(String s) {
// 1.去除首尾以及中间多余空格
StringBuilder sb = removeSpace(s);
// 2.反转整个字符串
reverseString(sb, 0, sb.length() - 1);
// 3.反转各个单词
reverseEachWord(sb);
return sb.toString();
}
public StringBuilder removeSpace(String 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++;
}
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 sb) {
int start = 0;
int end = 1;
while (start < sb.length()) {
while (end < sb.length() && sb.charAt(end) != ' ') {
end++; // 取出单个单词
}
reverseString(sb, start, end - 1); // 调用reverseString方法反转单词
start = end + 1; // 更新start到下一个单词首字母的位置
end = start + 1; // 更新end的位置
}
}
}
解法二:纯属娱乐
// 使用内置库函数解题
class Solution {
public String reverseWords(String s) {
// 除去开头和末尾的空白字符
s = s.trim();
// 正则匹配连续的空白字符作为分隔符分割
List<String> wordList = Arrays.asList(s.split("\\s+"));
Collections.reverse(wordList);
return String.join(" ", wordList);
}
}
注:本题java解法还有其他几种,需要了解,请移步代码随想录
题目五:左旋转字符串
题目描述:
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
思路分析:反转区间为前n的子串、反转区间为n到末尾的子串、反转整个字符串
class Solution {
public String reverseLeftWords(String s, int n) {
if (s == null || s.length() == 0) {
return s;
}
int len = s.length();
StringBuilder sb = new StringBuilder(s);
reverseString(sb, 0, n - 1); // 反转前n个字母
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--;
}
}
}
总结:
题一、题二、题五至于掌握了反转函数的实现,都可简单解决
题三转换为数组,使用双指针进行填充即可
题四需要自己实现三个函数,分别是:移除多余空格、将整个字符串反转、将每个单词反转。最后在主函数中对字符串依次进行操作,感觉这样把步骤拆分出来,比较容易搞明白!