344.反转字符串(双指针)
题目建议: 本题是字符串基础题目,就是考察 reverse 函数的实现,同时也明确一下 平时刷题什么时候用 库函数,什么时候 不用库函数
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
思路:定义两个指针(也可以说是索引下标),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。注意是字符数组,本质仍是数组,只不过存的不是常用的int型而是char型。对数组的操作仍然是一样的。
class Solution {
public void reverseString(char[] s) {
int left =0;
int right = s.length-1;
while(left<right){
//注意,temp要定义为char型
char temp = s[left];
s[left]=s[right];
s[right]=temp;
left++;
right--;
}
}
}
重点:是char temp;
541. 反转字符串II
题目建议:本题又进阶了,自己先去独立做一做,然后在看题解,对代码技巧会有很深的体会
给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例:
输入: s = "abcdefg", k = 2
输出: "bacdfeg"
思路:重点是实现规则的逻辑,以及StringBufffer、String的一些语句的应用。
实现一:
class Solution {
public String reverseStr(String s, int k) {
//将String类型转化为char型数组
char[] ch=s.toCharArray();
// 1. 每隔 2k 个字符的前 k 个字符进行反转
for(int i=0;i<ch.length;i+=2*k){
// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
if(i+k<=ch.length){
reverse(ch,i,i+k-1);
continue;
}
// 3. 剩余字符少于 k 个,则将剩余字符全部反转
reverse(ch,i,ch.length-1);
}
//因为是返回String类型,所以强转
return new String(ch);
}
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--;
}
}
}
重点语句:
- 将String类型转化为char型数组:char[] ch=s.toCharArray();
- 因为是返回String类型,所以强转:return new String(ch);
- StringBuffer是字符缓冲区,创建方法:StringBuffer res = new StringBuffer();
- StringBuffer的append方法,就是追加内容到当前StringBuffer对象的末尾res.append(xx);
https://blog.csdn.net/qq_36684107/article/details/83743899
5. String类中的substring方法,返回字符串的子字符串:
public String substring(int beginIndex) 或 public String substring(int beginIndex, int endIndex)
beginIndex -- 起始索引(包括), 索引从 0 开始。endIndex -- 结束索引(不包括)
剑指Offer 05.替换空格
题目建议: 对于线性数据结构,填充或者删除,后序处理会高效的多。好好体会一下
请实现一个函数,把字符串 s 中的每个空格替换成"%20"
示例 1:
输入:s = "We are happy."
输出:"We%20are%20happy."
随想录中给出的双指针的方法,是为了不占用额外的空间,直接增加数组的长度,C++可以更改string的长度,但是java不行,所以java中还是要开辟新的数组。
class Solution {
public String replaceSpace(String s) {
//用StringBuilder只是因为更快
StringBuilder res = new StringBuilder();
for(int i=0;i<s.length();i++){
if(s.charAt(i)==' '){
res.append("%20");
}else{
res.append(s.charAt(i));
}
}
return res.toString();
}
}
重点:String、StringBuffer的各种用法
151.翻转字符串里的单词
题目建议: 这道题目基本把 刚刚做过的字符串操作 都覆盖了,不过就算知道解题思路,本题代码并不容易写,要多练一练
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个
解题思路如下:
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
我不行了,写不出重点,因为每句代码都是重点!!!
class Solution {
public String reverseWords(String s) {
// 1.去除首尾以及中间多余空格
StringBuilder sb = removespace(s);
// 2.反转整个字符串
reverse(sb,0,sb.length()-1);
// 3.反转各个单词
reverseword(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;
}
/**
* 反转字符串指定区间[start, end]的字符
*/
public void reverse(StringBuilder sb,int start,int end){
while (start < end) {
char temp = sb.charAt(start);
//对于StringBuffer,将指定下标处的值改为指定值
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
}
public void reverseword(StringBuilder sb){
int start = 0;
int end = 1;
int n = sb.length();
while (start < n) {
while (end < n && sb.charAt(end) != ' ') {
end++;
}
reverse(sb, start, end - 1);
start = end + 1;
end = start + 1;
}
}
}
剑指Offer58-II.左旋转字符串
题目建议:题解中的解法如果没接触过的话,应该会想不到
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。提升一下本题难度:不能申请额外空间,只能在本串上操作
示例 1:
输入: s = "abcdefg", k = 2
输出: "cdefgab"
示例 2:
输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
限制:
1 <= k < s.length <= 10000
具体步骤为:
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder sb = new StringBuilder(s);
reverse(sb,0,n-1);
reverse(sb,n,sb.length()-1);
reverse(sb,0,sb.length()-1);
return sb.toString();
}
public void reverse(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--;
}
}
}
知识点总结
- String-->char[]: char[] ch=s.toCharArray();
- char[]-->String: return new String(ch);
- StringBuilder-->String: return sb.toString();
- String-->StringBuilder: StringBuilder sb = new StringBuilder(s);
- StringBuilder中使用的方法:sb.append(xxx);、sb.setCharAt(index,value);
- String中使用的方法:s.substring(beginIndex)---[begin,末尾] s.substring(beginIndex,endIndex)---[begin,end)