反转字符串
库函数仅仅是解题中的一部分, 所以这里使用库函数也是可以的
总体思路:只需要双指针, 左右互相调换就行了
新知识:
1. 字符串其实就是一种数组, 所以也要X【i】调用索引
2. 字符串就不是int了, 而是用char
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--;
}
}
}
反转字符串II
总体思路:这里发现其实就是每次按照2k来判断反转的, 所以遍历这里不应该写i++, 而是写i+=2k, 然后后面的反转和上题一样(这里的math.min没有很好理解啊)
细节:
1.题目给你的是字符串, 所以要先把它转换为字符数组, 同样最后return的是字符串, 直接new String(ch)
2.这里Math.min的比较是比较字符串length - 1和start + k - 1, 用来判断end指针的位置
3.记得每次反转完要left++. righ--;
(重点就是对反转start和end的调整; 对索引的使用, 这里已经转换为数组了, 所以直接【】)
class Solution {
public String reverseStr(String s, int k) {
//首先把字符串转为字符数组
char[] ch = s.toCharArray();
//注意i += 2*k
for(int i = 0; i < ch.length; i+= 2*k){
int start = i;
//这里要对end数值进行判断, 如果长度为k就全部这么多, 但有时候不足以k了,所以直接按照长度来算
int end = Math.min(ch.length - 1, start + k - 1);
while(start < end){
char temp = ch[start];
ch[start] = ch[end];
ch[end] = temp;
start++;
end--;
}
}
//再把字符数组传换为字符串
return new String(ch);
}
}
替换空格:
总体思路:
双指针
这种方法空间复杂度只有O(1)
我对该方法不是很熟练, 需要多多巩固
思路:
- 首先将数组扩容到换成%20之后的大小
- 然后利用双指针法, 从后向前替换空格
- i指向新长度的末尾, j指向旧长度的末尾
public String replaceSpace(String s) {
if(s == null || s.length() == 0){
return s;
}
//扩充空间,空格数量2倍
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(); //将扩容的sb加到原始字符串里
int right = s.length()-1;//右指针:指向扩展字符串的最后一个位置
char[] chars = s.toCharArray(); //把s转换为字符数组
//这里有个细节是要>=, 不然就判断不到第一个了
while(left>=0){
if(chars[left] == ' '){
chars[right--] = '0';
chars[right--] = '2';
chars[right] = '%';
}else{
chars[right] = chars[left];
}
left--;
right--;
}
//再次转换为string
return new String(chars);
}
StringBuilder方法:
但是由于创建里stringbuilder, 难免对空间有消耗
细节:
- 他这里是string, 那么就确实要加括号
- 对于string的索引, 不是加中括号, 而是加小括号, 而且string要用charAt(s)
- 最后还要搞个toString方法
- 这里的==判断记得是使用单引号
(或者也可以把string转换为toCharArray, 然后直接增强for循环)
class Solution {
public String replaceSpace(String s) {
if(s == null){
return null;
}
StringBuilder sb = new StringBuilder();
//应该是只有string的length方法才要用()
for(int i = 0; i< s.length(); i++){
if(s.charAt(i) == ' '){
sb.append("%20");
} else {
sb.append(s.charAt(i));
};
}
return sb.toString();
}
}
反转字符串里的单词
这道题太尼玛顶了, 直接涉及到了三个方法,每个方法都不容易理解, 今天只先尝试理解个大概了, 然后看看别人的讲解, 周末彻底把这个吃透
总体思路:
-
由于给的字符串乱七八糟的, 所以首先创造一个remove space的方法
(但是每个单词之前要间隔一个元素)
-
将整个字符串反转
-
将每个单词反转
不多说了, 直接上代码
class Solution {
public String reverseWords(String s) {
StringBuilder sb = removeSpace(s);
//翻转字符串
reverse(sb, 0, sb.length()-1);
//翻转每个单词
reverseEachWord(sb);
//转换为字符串再return
return sb.toString();
}
//创造去空格的方法
public StringBuilder removeSpace(String s){
int left = 0;
int right = s.length() - 1;
//去掉字符串开头的空白字符
while(left <= right && s.charAt(left) == ' '){
left++;
}
while(left <= right && s.charAt(right) == ' '){
right--;
}
//将字符串中间的多余空格去掉
StringBuilder sb = new StringBuilder();
while(left <= right){
char c = s.charAt(left);
//如果这个数不是空的可以加, 如果这个数前面不是空格, 就算是空的也加
if(c != ' ' || sb.charAt(sb.length() - 1) != ' '){
sb.append(c);
}
left++;
}
return sb;
}
//再创建不要返回的反转数组方法
public void reverse(StringBuilder sb, int left, int right){
while(left < right){
//这是stringbuilder的set方法, 反转如下
char temp = sb.charAt(left);
sb.setCharAt(left++, sb.charAt(right));
sb.setCharAt(right--, temp);
}
}
//创建反转单词的方法
public void reverseEachWord(StringBuilder sb){
int n = sb.length();
int start = 0, end = 0;
while(start < n){
//循环至单个单词的末尾
while(end < n && sb.charAt(end) != ' '){
end++;
}
//开始翻转单词
reverse(sb, start, end - 1);
//更新start, 去找下一个单词
start = end + 1;
end++;
}
}
}
左旋转字符串
新知识:
StringBuilder反转的语法有点不同:sb.setChatAt(x, y), x是要改变的位置索引, y是改变后的值
思路:
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
细节:
1.对于reverse方法的调用别搞错了
2.reverse方法是用遍历构造的, 别忘了++--
class Solution {
public String reverseLeftWords(String s, int n) {
int len = s.length();
//这里意思是把s塞到StringBuilder里面
StringBuilder sb = new StringBuilder(s);
reverse(sb, 0, n - 1);
reverse(sb, n, len - 1);
//直接用链式法, 先全部反转, 然后再转换为字符串
return sb.reverse().toString();
}
public void reverse(StringBuilder sb, int left, int right){
while(left < right){
char temp = sb.charAt(left);
//他这里把left给修改了, 自然就要temp来保存原始值
sb.setCharAt(left, sb.charAt(right));
sb.setCharAt(right, temp);
left++;
right--;
}
}
}