力扣151 反转字符串中的单词
题目:
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例:
输入:s = " hello world "
输出:"world hello"
解释:反转后的字符串中不能存在前导空格和尾随空格。
思路:
1.直接思路
class Solution {
public String reverseWords(String s) {
char[] ch=s.toCharArray();//原
if(s==null||s.length() == 0){
return s;
}
StringBuilder sb=new StringBuilder();//新
int i = ch.length-1;
while(i>=0){
while(i>=0&&ch[i]==' '){//跳过空格
i--;
}
int right=i;//记录单词结束位置
while(i>=0&&ch[i]!=' '){
i--;//找到单词起始位置
}
for(int j=i+1;j<=right;j++){//j从单词起始位置到结束位置
sb.append(ch[j]);
if(j == right){
sb.append(" ");//空格
}
}
}
//删除最后的空格
sb.deleteCharAt(sb.length()-1);
return sb.toString();
}
}
tips:
s == null; 表示s还没有占用存储空间。
s.length() == 0; 表示s占用存储空间,但是其中还没有元素。
2.限制空间复杂度为O(1)
解题思路如下:
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
举个例子,源字符串为:"the sky is blue "
- 移除多余空格 : "the sky is blue"
- 字符串反转:"eulb si yks eht"
- 单词反转:"blue is sky the"
class Solution {
public String reverseWords(String s) {
if(s.length()==0||s==null){
return s;
}
//1.移除多余空格
StringBuilder s1=removeSpace(s);
//2.将整个字符串反转
int start=0;
int end=s1.length()-1;
StringBuilder s2=reverseString(s1,start,end);
//3.将每个单词反转
reverseEch(s2);
return s2.toString();
}
//移除多余空格
private StringBuilder removeSpace(String s) {
StringBuilder sb=new StringBuilder();
int start=0;
int end=s.length()-1;
//去除两端多余空格
while(s.charAt(start)==' '){start++;}
while(s.charAt(end)==' '){end--;}
while(start<=end){
//去除中间多余的空格:如果sb最后无空格,那么就保留
if(s.charAt(start)!=' '|| sb.charAt(sb.length() - 1) != ' '){
sb.append(s.charAt(start));
}
start++;
}
return sb;
}
//将整个字符串反转
private StringBuilder 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--;
}
return sb;
}
//将每个单词反转
private void reverseEch(StringBuilder sb){
int start = 0;
int end = 1;
int n = sb.length();
while (start < n) {
while (end < n && sb.charAt(end) != ' ') {//end停在距离start的第一个空格处
end++;
}
reverseString(sb, start, end - 1);
start = end + 1;//start到下一个单词第一位
end = start + 1;//end继续重复上述步骤
}
}
}
StringBuilder setCharAt() 方法设置字符ch指定的索引。 String CharAt() 方法 参数只有一个index,就是取索引位置的字符。
String字符串的特点
-
Java程序中所有的双引号字符串,都是String类型的对象。
-
字符串不可变,它们的值在创建后不能被更改。
-
虽然String的值是不可变的,但是它们可以被共享。
tips:
其实当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。 eg:只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。 先整体反转再局部反转,实现了反转字符串里的单词。 后来发现反转字符串还有一个牛逼的用处,就是达到左旋的效果。 KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。 其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。