344.反转字符串
思路:使用双指针完成就地逆置,思路和操作都比较简单
class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
char temp;
while(left < right) {
temp = s[right];
s[right] = s[left];
s[left] = temp;
left++;
right--;
}
}
}
541.反转字符串Ⅱ
思路:根据题目中规定的反转规则进行模拟。题目大意总体可以概括为:每隔2k个反转前k个,尾数不够k个时候全部反转。
class Solution {
public String reverseStr(String s, int k) {
char[] arr = s.toCharArray();
for(int i = 0; i < arr.length; i += 2*k) {
int start = i;
int end = Math.min(arr.length - 1, start + k -1);
while(start < end) {
char temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
return new String(arr);
}
}
小结:值得注意的点
- 当需要固定规律一段一段去处理字符串的时候,要想想在for循环表达式上调整。利用i每次变化2k,即每循环一次便对2k个字符中的前k个字符反转。
- end的取值需要好好思考,end的值每次和star+k-1的值进行比较并取最小,这样可以保证每次都能取到对应的边界值
剑指offer05.替换空格
思路:使用substring来拼接字符串或者双指针法。
用Java中substring()来进行字符串拼接
class Solution {
public String replaceSpace(String s) {
if (s.length() == 0) {
return s;
}
int length = s.length();
for(int i = 0; i < length;) {
if(s.charAt(i) == ' ') {
s = s.substring(0, i) + "%20" + s.substring(i+1, length);
length = s.length();
i += 3;
} else {
i++;
}
}
if(s.charAt(0) == ' ') {
s = "%20" + s.substring(1, length-1);
}
if(s.charAt(length-1) == ' ') {
s = s.substring(0, length-2) + "%20";
}
return s;
}
}
小结:值得注意的点
- 对字符串长度为0时的处理
- 先处理两端内的空格,最后处理两端的空格
双指针法
class Solution {
public String replaceSpace(String s) {
if(s.length() == 0) {
return s;
}
if(s.equals(" ")) {
return "%20";
}
int num = 0;
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) == ' ') {
num++;
}
}
char[] arr = new char[s.length()+2*num];
int p = arr.length - 1;
int q = s.length() - 1;
while (q >= 0) {
if(s.charAt(q) == ' ') {
arr[p] = '0';
arr[p-1] = '2';
arr[p-2] = '%';
p -= 3;
q--;
} else{
arr[p] = s.charAt(q);
p--;
q--;
}
}
return new String(arr);
}
}
小结:值得注意的点
- 先根据空格的数量来计算出新数组所需空间,记得要减掉空格的数量
- 从新数组尾端开始香前不断插入原来字符串中的字符,遇到空格则插入%20
- 对于字符串长度为0以及只包含一个空格的处理
151.反转字符串中的单词
思路:这道题综合了字符串的多种操作。首先考虑到要移除多余的空格,其次将整个字符串反转,最后将每个单词进行反转,便可以得到对应的结果。
class Solution {
public String reverseWords(String s) {
// 1.去除首尾以及中间多余空格
StringBuilder sb = removeSpace(s);
// 2.反转整个字符串
reverseString(sb, 0, sb.length() - 1);
// 3.反转各个单词
reverseEachWord(sb);
return sb.toString();
}
private 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 reverseString(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--;
}
}
private void reverseEachWord(StringBuilder sb) {
int start = 0;
int end = 1;
int n = sb.length();
while (start < n) {
while (end < n && sb.charAt(end) != ' ') {
end++;
}
reverseString(sb, start, end - 1);
start = end + 1;
end = start + 1;
}
}
}
小结:值得注意的点
- 对首尾两端连续出现的空格的清除操作使用while
剑指offer58.左旋字符串
思路:方法一:利用Java中substring()来进行字符串拼接,方法二:整体反转+局部反转就可以实现反转单词顺序的目的。该题和151.反转字符串中的单词有异曲同工之妙,先整体反转,后局部反转等价于先局部反转,后整体反转。
用Java中substring()来进行字符串拼接
class Solution {
public String reverseLeftWords(String s, int n) {
return s.substring(n, s.length()) + s.substring(0, n);
}
}
整体反转+局部反转
class Solution {
public String reverseLeftWords(String s, int n) {
char[] arr = s.toCharArray();
reverse(arr, 0,n-1);
reverse(arr, n, s.length() - 1);
reverse(arr, 0, s.length() - 1);
return new String(arr);
}
private void reverse(char[] arr, int left, int right) {
char temp;
while(left < right) {
temp = arr[right];
arr[right] = arr[left];
arr[left] = temp;
left++;
right--;
}
}
}
小结:可以通过局部反转+整体反转 达到左旋转的目的
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
值得注意的是对字符串数组中进行反转时边界位置的确定