目录
344.反转字符串
原地的话采用双指针,互相交换
class Solution {
/**
* 翻转字符串--->原地修改数组
*
* @param s
*/
public void reverseString(char[] s) {
//双指针
int len = s.length;
int left = 0, right = len - 1;//left<len/2,right>len/2
for (left = 0; left < len / 2; left++) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
right--;
}
}
}
541.反转字符串II
重点是,start到哪儿了,而且要翻哪个区域。用一个比较长字符串的模拟一下
class Solution {
/**
* 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
* 如果剩余字符少于 k 个,则将剩余字符全部反转。
* 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
*
* @param s
* @param k
* @return
*/
public String reverseStr(String s, int k) {
char[] chars = s.toCharArray();
int len = chars.length;
int start = 0;
while (len > 0) {
if (len < k) {
reversePartStr(chars, start, chars.length - 1);
break;
} else if ((len >= k) && (len < 2 * k)) {
//翻转前k个字符
reversePartStr(chars, start, start + k - 1);
break;
} else {
reversePartStr(chars, start, start + k - 1);//翻转前k个字符
len -= 2 * k;
start += 2 * k;
}
}
return String.valueOf(chars);
}
public void reversePartStr(char[] chars, int start, int end) {//翻转索引start到end部分
if (start > end) {
return;
}
int temp = (end - start + 1) / 2;
for (int i = start; i < start + temp; i++) {
char mob = chars[i];
chars[i] = chars[end];
chars[end] = mob;
end--;
}
}
}
剑指Offer 05.替换空格
其实本来第一反应是转成char数组去做,但是空格要转成“%20”并不是一个字符,之后想到是否可以用buffer的replace直接做。
class Solution {
/**
* 把s里面的空格替换成%20
*
* @param s
* @return
*/
public String replaceSpace(String s) {
StringBuffer buffer = new StringBuffer(s);
for (int i = 0; i < buffer.length(); i++) {
if (' ' == buffer.charAt(i)) {
buffer.replace(i, i + 1, "%20");
}
}
return buffer.toString();
}
}
然后看了别人的思路之后发现利用char数组的话可以先扩容,然后利用双指针,一个指向扩容之后的结尾,一个指向本来的结尾,进行数据填充。
151.反转字符串中的单词
更多的利用了库函数去掉首尾的空格,并且利用正则匹配多个空格去分割
然后字符串数组里面进行交换,最后拼成结果。
class Solution {
/**
* 反转字符串中单词的顺序
* 输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。
* 返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
*
* @param s
* @return
*/
public String reverseWords(String s) {
StringBuffer ans = new StringBuffer();
s = s.trim();
s = s.replace("\\s+", " ");
String[] strs = s.split("\\s+");
int left = 0, right = strs.length - 1;
for (left = 0; left < strs.length / 2; left++) {
String temp = strs[left];
strs[left] = strs[right];
strs[right] = temp;
right--;
}
for (int i = 0; i < strs.length - 1; i++) {
ans.append(strs[i]);
ans.append(" ");
}
ans.append(strs[strs.length - 1]);
return ans.toString();
}
}
看了解析之后如果空间复杂度为O(1)的话,可以使用快慢指针,即移除空格,慢指针维护边界,快指针去找符合的字符,然后每多个空格添加单个空格。
剑指offer58-II.左旋转字符串
第一反应还是用StringBuffer,开一个长度为k的新字符串,然后拼在原字符串后面。
但是如果空间复杂度为O(1)的话不使用额外空间只在原字符串上面操作----->使用整体翻转然后局部翻转的策略
* 左旋字符串----> * 1.翻转前n个字符串 * 2.翻转剩下的字符串 * 3.翻转整个字符串
class Solution {
/**
* 左旋字符串---->
* 1.翻转前n个字符串
* 2.翻转剩下的字符串
* 3.翻转整个字符串
*
* @param s
* @param n
* @return
*/
public String reverseLeftWords(String s, int n) {
char[] chars = s.toCharArray();
ReverseChar(chars, 0, n - 1);
ReverseChar(chars, n, s.length() - 1);
ReverseChar(chars, 0, s.length() - 1);
return new String(chars);
}
public void ReverseChar(char[] chars, int start, int end) {//从start到end部分进行反转
//双指针
if (start >= end) {
return;
}
int mid = (start + end + 1) / 2;
while (start < mid) {
char temp = chars[start];
chars[start] = chars[end];
chars[end] = temp;
start++;
end--;
}
}
}