代码随想录算法训练营第八天|344.反转字符串 、541. 反转字符串II、剑指Offer 05.替换空格 、151.翻转字符串里的单词、剑指Offer58-II.左旋转字符串
一. 字符串相关算法题
思路
- 使用左右双指针分别指向字符串数组的头和尾
- 交换左右指针的字符,然后左右指针前移right–和left ++,直到两个指针相遇
class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length-1;
char temp;
while (left<right){
temp = s[left];
s[left] = s[right];
s[right] = temp;
right--;
left ++ ;
}
}
}
思路
- 根据题目可以简化为两种情况,剩余字符长度小于等于2k且大于等于k;剩余字符长度小于k,然后针对这两种情况通过双指针法交换字符
- 判断剩余长度小于等于2k大于等于k时可以简化判定条件为:i+k<=String.length,此时的左右指针分别为:i,i+k-1
- 除了上面的情况就是长度小于k了:此时左右指针分别为:i,String.length()-1;
- 要注意的是可以在for循环中简化循环操作,每次i的跨度为2*k
class Solution {
public String reverseStr(String s, int k) {
char[] chars = s.toCharArray();
int left = 0;
int rigih = 0;
for (int i = 0; i < chars.length; i+=2*k) {
if (i+k<= chars.length){
reverseSubArray(i,i+k-1,chars);
continue;
}
reverseSubArray(i, chars.length-1,chars);
}
return new String(chars);
}
private void reverseSubArray(int left, int right, char[] chars){
char temp;
while (left<right){
temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
}
通过复制字符串的方式
思路
- 创建一个StringBuilder,然后遍历字符串,遇见空格就在后面拼接%20
class Solution {
public String replaceSpace(String s) {
char[] chars = s.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
if (chars[i]==' '){
sb.append("%20");
}else {
sb.append(chars[i]);
}
}
return sb.toString();
}
}
通过双指针的方式
- 首先创建字符串长度为空格数,然后空格数乘以3拼接到原来的字符串中
- 然后定义左右双指针分别指向原来字符串末端和新字符串末端
- 从后向前遍历左指针遇到非空字符放到右指针,遇到空字符,右指针向前填充%20就这样直至结束
class Solution {
public String replaceSpace(String s) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i)==' '){
stringBuilder.append(" ");
}
}
int left = s.length()-1;
s+=stringBuilder.toString();
int right = s.length()-1;
char[] chars = s.toCharArray();
while (left>=0){
System.out.println(left +"->"+right+" "+ chars[left]);
if (chars[left]==' '){
chars[right--] = '0';
chars[right--] = '2';
chars[right] = '%';
}else {
chars[right] = chars[left];
}
left--;
right--;
}
return new String(chars);
}
思路
- 去除字符串中多余的空格
- 反转字符串
- 反转字符串中每个单词
class Solution {
public String reverseWords(String s) {
StringBuilder stringBuilder = removeSpace(s);
char[] chars = stringBuilder.toString().toCharArray();
reverse(chars,0, chars.length-1);
int start = 0;
int end = 1;
while (start< chars.length){
while (end< chars.length && chars[end]!=' ') end++;
reverse(chars,start,end-1);
start = end+1;
end = start+1;
}
return new String(chars);
}
private void reverse(char[] chars,int left, int right){
char temp ;
while (left<right){
temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
private StringBuilder removeSpace(String s){
int left = 0;
int right = s.length()-1;
while (s.charAt(left)==' ') left++;
while (s.charAt(right)==' ') right--;
StringBuilder stringBuilder = new StringBuilder();
while (left<=right){
if (s.charAt(left)!=' '|| s.charAt(left-1)!=' '){
stringBuilder.append(s.charAt(left));
}
left++;
}
return stringBuilder;
}
}
字符串拼接
思路
- 创建一个新字符串以n为分界线先拼接后半段再拼接前半段
class Solution {
public String reverseLeftWords(String s, int n) {
char[] chars = s.toCharArray();
int left = 0;
int right = n;
StringBuilder stringBuilder = new StringBuilder();
while (right<chars.length){
stringBuilder.append(chars[right++]);
}
while (left<n){
stringBuilder.append(chars[left++]);
}
return stringBuilder.toString();
}
}
通过反转实现
思路
- 以n为分界线反转前后子串
- 反转整个字符串
class Solution {
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);
}
public void reverse(char[] chars,int left, int right){
char temp ;
while (left<right){
temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
}