151.反转字符串中的单词
题目链接:151. 反转字符串中的单词 - 力扣(LeetCode)
视频链接:代码随想录 (programmercarl.com)
第一想法
使用split函数然后倒序相加
代码随想录想法
先去除空格,再将整个字符串反转,再将单个单词反转
去除空格
如果时间复杂度为O(n)的话,新new StringBuilder sb追加加字符即可。既要判断非空格字符原样追加又要保证单词间距一个空格的距离的逻辑是
if(s.charAt(start)!=' '||sb.charAt(sb.length()-1)!=' ')//如果当前字符不为空或者已追加新单词后没有空格 sb.append(s.charAt(start));
代码
class Solution {
public String reverseWords(String s) {
//去除空格
StringBuilder sb = RemoveSpace(s);
//反转整个字符串
reverseWholeWord(sb,0,sb.length()-1);
//反转单个字符串
ReverseSingleWord(sb);
//返回
return sb.toString();
}
public StringBuilder RemoveSpace(String s){
int start = 0;
int end = s.length() - 1;
StringBuilder sb = new StringBuilder();
while (s.charAt(start)==' ')start++;//去除前导空字符
while (s.charAt(end)==' ')end--;//去除后导空字符
while (start<=end){
if(s.charAt(start)!=' '||sb.charAt(sb.length()-1)!=' ')//如果当前字符不为空或者已追加新单词后没有空格
sb.append(s.charAt(start));
start++;
}
return sb;
}
public void reverseWholeWord(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--;
}
}
public void ReverseSingleWord(StringBuilder sb){
int start = 0;
int end = 1;
while (start < sb.length()) {
while (end<sb.length()&&sb.charAt(end)!=' ')
end++;
reverseWholeWord(sb,start,end-1);
start = end + 1;
end = start + 1;
}
}
}
class Solution2 {
public String reverseWords(String s) {
char[] oldCharArray = s.toCharArray();
char[] newCharArray = new char[oldCharArray.length];
int newIndex = 0;
int i = oldCharArray.length - 1;
while (i>=0){
while (i>=0&&oldCharArray[i]==' ')i--;//去除末尾空格,循环结束时,i指向第一个非空格元素
int right = i;//设定右边界
while (i>=0&&oldCharArray[i]!=' ')i--;//跳过一个单词,循环结束时,i指向该元素的左边界。首元素则指向-1,非首元素则指向前面的空格
//单独获取一个单词的边界[i+1,right];
for(int j = i+1;j<=right;j++){
newCharArray[newIndex++] = oldCharArray[j];
if(j==right)//如果抵达右边界,则末尾加一个空格
newCharArray[newIndex++] = ' ';
}
}
if(newIndex == 0) return "";
else return new String(newCharArray,0,newIndex - 1);
}
}
卡码网55.右旋字符串
题目链接:55. 右旋字符串(第八期模拟笔试) (kamacoder.com)
文档/视频链接:代码随想录 (programmercarl.com)
第一想法
定义双端队列,右端出n个元素加入到左端。但是这样做就没意义了。
或者先将整个字符串反转,分别将子字符串反转回来。
假设字符串为"abcdefg" ,n = 2
先反转整体"gfedcba",
再反转局部:[0,n-1],变成 fg edcba;
[n,length -1]变成 fg abcde
代码随想录想法
看了感觉和第一想法差不多。
代码
class Solution2{
public String RightReverse(String s,int n){
char[] charArray = s.toCharArray();
//先反转整体的
Reverse(charArray,0,charArray.length-1);
//再反转局部
Reverse(charArray,0,n-1);
Reverse(charArray,n,charArray.length-1);
return new String(charArray);
}
public void Reverse(char[] s, int start,int end){
while (start<end){
char temp = s[start];
s[start] = s[end];
s[end] = temp;
start++;
end--;
}
}
}
KMP留到以后补吧,今天就暂且不看了。