class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while(left < right){
char tmp = s[left];
s[left] = s[right];
s[right] = tmp;
left++;
right--;
}
}
}
思路:
-
定义双指针:
left
指针从字符数组的开头开始。right
指针从字符数组的末尾开始。
-
反转字符:
- 当
left
小于right
时,将s[left]
和s[right]
的字符交换。 - 交换后,
left
指针向右移动,right
指针向左移动。
- 当
-
循环直至指针相遇:
- 这样确保了数组的左半部分和右半部分都得到了反转。
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
//每隔2k个字符的前k个字符翻转
for(int i = 0; i < ch.length; i += 2*k){
if(i+k <= ch.length){
reverse(ch, i, i+k-1);
continue;
}else{
//剩余字符少于 k 个,则将剩余字符全部反转
reverse(ch, i, ch.length-1);
}
}
return String.valueOf(ch); //转换为str输出
}
public void reverse(char[] ch, int i, int j){
while(i<j){
char temp = ch[i];
ch[i] = ch[j];
ch[j] = temp;
i++;
j--;
}
}
}
思路:
-
将字符串转为字符数组: 使用
s.toCharArray()
将字符串转换为字符数组,方便后续的操作。 -
分段处理:
- 从索引 0 开始,每隔 2k 个字符,就对这 2k 个字符的前 k 个字符进行反转。这个操作使用了一个循环,循环变量
i
每次增加 2k。 - 对于每个段,如果当前索引
i
加上 k 小于等于字符数组的长度,那么就将索引从i
到i+k-1
的字符反转。 - 如果当前索引
i
加上 k 大于字符数组的长度,那说明已经处理到了字符数组的末尾,并且剩余的字符不足 k 个,此时将索引从i
到字符数组末尾的所有字符进行反转。
- 从索引 0 开始,每隔 2k 个字符,就对这 2k 个字符的前 k 个字符进行反转。这个操作使用了一个循环,循环变量
-
字符反转:
- 使用一个辅助函数
reverse
对字符数组中的一段进行反转。reverse
函数使用了双指针技术,一个指针从段的开头开始,另一个指针从段的末尾开始,将这两个指针指向的字符交换,然后两个指针分别向中间移动,直到两个指针相遇。
- 使用一个辅助函数
-
返回结果: 使用
String.valueOf(ch)
将字符数组转换回字符串,并作为结果返回。
class Solution {
public String replaceSpace(String s) {
if(s == null || s.length() == 0){
return 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 = s + str.toString();
int right = s.length() - 1; //右指针:指向扩展字符串最后一个位置
char[] ch = s.toCharArray();
while(left >= 0){
if(ch[left] == ' '){
ch[right--] = '0';
ch[right--] = '2';
ch[right] = '%';
}else{
ch[right] = ch[left];
}
left--;
right--;
}
return new String(ch);
}
}
思路:
-
检查字符串是否为空: 如果输入的字符串
s
为空或长度为0,则直接返回输入的字符串。 -
初始化 StringBuilder: 使用
StringBuilder
来计算新字符串中需要增加的空间。 -
遍历原字符串: 对输入的字符串
s
进行遍历,每当找到一个空格时,在StringBuilder
中追加两个空格。这是因为原字符串中的空格只占一个字符,而"%20"有三个字符,所以需要在原有的基础上增加两个位置。 -
检查是否有空格: 如果
StringBuilder
的长度为0,说明原字符串中没有空格,因此直接返回原字符串。 -
替换空格: 在原字符串后面追加
StringBuilder
中的内容,然后定义两个指针,左指针指向原字符串的最后一个字符,右指针指向新字符串的最后一个字符。接下来,进行以下操作:
- 如果左指针指向的字符是空格,则将右指针指向的位置依次设置为"0"、"2"和"%"。
- 如果左指针指向的字符不是空格,则将右指针指向的位置设置为左指针指向的字符。
每次操作后,左右指针都往左移动一个位置。
-
返回新字符串: 最后,使用新的字符数组创建一个新的字符串并返回。
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();
}
private 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; //设置起始指针为0,表示从字符串的开始位置开始
int end = 1; //设置结束指针为1,用于找到每个单词的结束位置
int n = sb.length(); //获取字符串的长度
while(start < n){ //当起始指针仍在字符串长度内时,继续执行循环
while(end < n && sb.charAt(end) != ' '){ //当结束指针在字符串长度内并且指向的字符不是空格时,移动结束指针
end++; //它会检查 end 指针所指向的字符是否不是空格,如果不是空格,说明当前字符仍属于当前单词,因此 end 指针会向前移动
}
reverseString(sb, start, end - 1);//反转从起始指针到结束指针之间的字符,即反转当前单词
start = end + 1; //将起始指针移动到下一个单词的开始位置
end = start + 1; //将结束指针设置为起始指针的下一个位置,准备开始下一个单词的查找
}
}
}
思路:
-
去除多余空格: 使用
removeSpace
函数移除字符串s
的前后以及中间连续的空格。这个函数通过两个指针(start 和 end)定位到第一个和最后一个非空格字符。然后,它从头到尾遍历字符串,并只在以下情况下将字符添加到StringBuilder
中:- 当前字符不是空格;
- 或者
StringBuilder
的最后一个字符不是空格。
-
反转整个字符串: 使用
reverseString
函数反转整个字符串。这个函数通过两个指针(start 和 end),从两端向中间移动,交换两端的字符。 -
反转每个单词: 使用
reverseEachWord
函数反转每个单词。这个函数首先设置两个指针(start 和 end)。开始和结束指针的目的是找到每个单词的开始和结束位置。每次找到一个单词后,使用reverseString
函数将这个单词反转。
class Solution {
public String reverseLeftWords(String s, int n) {
int len=s.length();
StringBuilder sb=new StringBuilder(s);
reverseString(sb,0,n-1);//注意左闭右闭区间
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--;
}
}
}
思路:
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串