344.反转字符串 541. 反转字符串II 剑指Offer 05.替换空格 151.翻转字符串里的单词 剑指Offer58-II.左旋转字符串
344.反转字符串
1.思路
对于字符串,我们定义两个指针(也可以说是索引下标),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。
swap可以有两种实现。
一种就是常见的交换数值:
int tmp = s[i];
s[i] = s[j];
s[j] = tmp;
一种就是通过位运算:
s[i] ^= s[j];
s[j] ^= s[i];
s[i] ^= s[j];
2.代码实现
注意题目要求:在原数组上实现
class Solution {
public void reverseString(char[] s) {
int l=0;
int r=s.length-1;
while(l<r){
s[l]^=s[r];
s[r]^=s[l];
s[l]^=s[r];
l++;
r--;
}
}
}
}
541.反转字符串II
1.思路
遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
- 每隔 2k 个字符的前 k 个字符进行反转
- 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
2.代码实现
class Solution {
public String reverseStr(String s, int k) {
char[] ch=s.toCharArray();
int length=ch.length;
for(int i=0;i<length;i+=2*k){
if(i+k<length){//这个地方视频里讲的边界问题还是不理解 但我没加=也过了
int l=i;
int r=i+k-1;
while(l<r){
ch[l]^=ch[r];
ch[r]^=ch[l];
ch[l]^=ch[r];
l++;
r--;
}
}
else{
int l=i;
int r=length-1;
while(l<r){
ch[l]^=ch[r];
ch[r]^=ch[l];
ch[l]^=ch[r];
l++;
r--;
}
}
}
return new String(ch);
}
}
剑指Offer 05.替换空格
1.思路
首先扩充数组到每个空格替换成"%20"之后的大小。
然后从后向前替换空格,也就是双指针法,过程如下:
i指向新长度的末尾,j指向旧长度的末尾。
如果i处不是’ ',则直接赋值给j处
否则 j处赋值%20
2.代码实现
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 l=s.length()-1;
s+=str.toString();
int r=s.length()-1;
char[] chars= s.toCharArray();
while(l>=0){
if(chars[l]==' ')
{
chars[r--]='0';
chars[r--]='2';
chars[r]='%';
}
else{
chars[r]=chars[l];
}
l--;
r--;
}
return new String(chars);
}
}
151.翻转字符串里的单词
1.思路
这道题有点难度。主要思路是先移除多余空格,再将整个字符串反转,最后把单词逐个反转。
难点是移除多余空格中需要在每个单词结束后添加一个空格。和单纯的去除某个元素不一样。
有一些细节需要注意,比如reverseEachwords中判断end的循环结束条件时,应该是<=,因为end在这里指向每一个单词最后一个字母的后一个位置。
2.代码实现
class Solution {
public char[] removespace(char[] chars){
int slow=0;
for(int fast=0; fast<chars.length; fast++){
//fast删除所有空格
if(chars[fast]!= ' '){
if(slow!=0)
chars[slow++]=' ';//每个单词结束后手动添加空格
while(fast<chars.length && chars[fast]!=' ')
chars[slow++]=chars[fast++];
}
}
char[] newchars= new char[slow];
System.arraycopy(chars, 0, newchars, 0, slow);
return newchars;
}
public void reverse(char[] chars,int left,int right){
while(left<right){
chars[left]^=chars[right];
chars[right]^=chars[left];
chars[left]^=chars[right];
left++;
right--;
}
}
public void reverseEachwords(char[] chars){
int start=0;
for(int end=0; end<=chars.length;end++){
if(end==chars.length|| chars[end]==' '){// //end <= s.length() 这里的 = ,是为了让 end 永远指向单词末尾后一个位置,这样 reverse 的实参更好设置
reverse(chars,start,end-1);
start=end+1;
}
}
}
public String reverseWords(String s) {
char[] chars=s.toCharArray();
chars=removespace(chars);
reverse(chars,0,chars.length-1);
reverseEachwords(chars);
return new String(chars);
}
}
剑指Offer58-II.左旋转字符串
1.思路
可以通过局部反转+整体反转 达到左旋转的目的。
具体步骤为:
反转区间为前n的子串
反转区间为n到末尾的子串
反转整个字符串
最后就可以达到左旋n的目的,而不用定义新的字符串,完全在本串上操作。
2.代码实现
class Solution {
public void reverse(char[] chars,int start,int end){
while(start<end){
chars[start]^=chars[end];
chars[end]^=chars[start];
chars[start]^=chars[end];
start++;
end--;
}
}
public String reverseLeftWords(String s, int n) {
char[] chars=s.toCharArray();
reverse(chars,0,n-1);
reverse(chars,n,chars.length-1);
reverse(chars,0,chars.length-1);
return new String(chars);
}
}