344.反转字符串
思路:本题用双指针法,从头和尾同时调换顺序即可。
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;
left++;
right--;
}
}
}
541. 反转字符串II
思路:按照参数k的值,每次移动2k,周期性移动,2k的元素里前k个元素也是用双指针法进行反转。
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
int left = 0;
int right = 0;
char temp;
for(int i=0; i<ch.length; i+=2*k){
left = i;
right = Math.min(ch.length - 1,left + k - 1);
while(left < right){
temp = ch[left];
ch[left] = ch[right];
ch[right] = temp;
left++;
right--;
}
}
return new String(ch);
}
}
剑指Offer 05.替换空格
思路:用双指针法,不过这道题有个坑就是从前往后遍历和从后往前遍历的问题。从前往后的话遇到一个空格就会导致后面全部元素同时移动,时间复杂度O(n²);而从后往前的话,就解决了这个问题,时间复杂度O(1)。
class Solution {
public String replaceSpace(String s) {
StringBuilder str = new StringBuilder();
for(int i=0; i<s.length(); i++){
if(s.charAt(i) == ' '){
str.append(" ");
}
}
int left = s.length() - 1;
s = s + str;
int right = s.length() - 1;
char[] ch = s.toCharArray();
while(left >= 0){
if(ch[left] == ' '){
ch[right--] = '0';
ch[right--] = '2';
ch[right] = '%';
}else{
ch[right] = ch[left];
}
right--;
left--;
}
return new String(ch);
}
}
151.翻转字符串里的单词
思路:
1.去除首尾以及中间多余空格
2.反转整个字符串
3.反转各个单词
class Solution {
public String reverseWords(String s) {
/**
* 1.去除首尾以及中间多余空格
* 2.反转整个字符串
* 3.反转各个单词
*/
StringBuilder sb = removeWords(s);
reverseString(sb, 0, sb.length()-1);
reverseEachString(sb);
return sb.toString();
}
private StringBuilder removeWords(String s){
StringBuilder sb = new StringBuilder();
int left = 0;
int right = s.length()-1;
while(s.charAt(left) == ' '){left++;}
while(s.charAt(right) == ' '){right--;}
while(left <= right){
char c = s.charAt(left);
if(c != ' ' || sb.charAt(sb.length()-1) != ' '){
sb.append(c);
}
left++;
}
return sb;
}
private void reverseString(StringBuilder sb, int left, int right){
while(left < right){
char temp = sb.charAt(left);
sb.setCharAt(left, sb.charAt(right));
sb.setCharAt(right, temp);
left++;
right--;
}
}
private void reverseEachString(StringBuilder sb){
int left = 0;
int right = 1;
int n = sb.length();
while(left < n){
while(right<n && sb.charAt(right)!= ' '){
right++;
}
reverseString(sb, left, right-1);
left = right + 1;
right = left + 1;
}
}
}
剑指Offer58-II.左旋转字符串
思路:暴力法new一个字符串添加就行了,但是我们要求不使用额外空间。
为了让本题更有意义,提升一下本题难度:不能申请额外空间,只能在本串上操作。
解法:
1.反转前k个 bacdefg
2.反转后k个 bagfedc
3.反转全部 cdefgab
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder sb = new StringBuilder(s);
//1.反转前k个 bacdefg
reverse(sb, 0, n-1);
//2.反转后k个 bagfedc
reverse(sb, n, sb.length()-1);
//3.反转全部 cdefgab
reverse(sb, 0, sb.length()-1);
return sb.toString();
}
private 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--;
}
}
}