344.反转字符串
典中典,转化为reverse array elements
public void reverseString(char[] s) {
int left = 0, right = s.length - 1;
while (left < right){
char tmp = s[left];
s[left++] = s[right];
s[right--] = tmp;
}
}
541. 反转字符串II
使用滑动窗口进行字符串的部分反转
需要注意滑动窗口的右界限,避免IndexOutOfBoundException
public String reverseStr(String s, int k) {
if (s.length() == 1 || k == 1) return s;
char[] chs = s.toCharArray();
int left = 0, right = Math.min(2 * k - 1, s.length() - 1);
while(right < s.length()){
int i = Math.min(left + k - 1, right);
reverse(chs, left, i);
if (right == s.length() - 1) break;
left = right + 1;
right = Math.min(s.length() - 1, right + 2 * k);
}
return String.valueOf(chs);
}
private void reverse(char[] chs, int left, int i){
while(left < i){
char tmp = chs[left];
chs[left++] = chs[i];
chs[i--] = tmp;
}
}
剑指Offer 05.替换空格
本解法使用StringBuilder进行构造新字符串,比较直观
另一种思路为使用char[]从后向前进行填充character,需要提前判断char[]的长度
(长度为s.length - count of space + count of space * 3)
char[]思路时间复杂度较高(也为O(n),但是为2*n)
public String replaceSpace(String s) {
if (s == null || s.length() == 0) return s;
StringBuilder sb = new StringBuilder();
String token = "%20";
for (int i = 0; i < s.length(); i++){
if (s.charAt(i) == ' ') sb.append(token);
else sb.append(s.charAt(i));
}
return sb.toString();
}
使用StringBuilder速度较快,仅需循环一次
151.翻转字符串里的单词
使用正则表达式把字符串分割成单词子字符串数组
在return前需要注意去掉最末尾的空格,也可使用 return res.strip();
public String reverseWords(String s) {
s = s.strip();
String[] tokens = s.split("\\s+");
StringBuilder sb = new StringBuilder();
for (int i = tokens.length - 1; i >= 0; i--){
sb.append(tokens[i]);
sb.append(" ");
}
String res = sb.toString();
return res.substring(0, res.length() - 1);
}
剑指Offer58-II.左旋转字符串
题解提供思路为:
- 先反转前n个字符组成的子字符串
- 再反转后length - n个字符组成的子字符串
- 反转整个字符串
另外,题解中提供的两种反转子字符串的helper方法值得学习
1. 使用StringBuilder的setChharAt方法
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--;
}
}
2. 使用^=对char[]进行复制达到成对反转目的
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--;
}
}
本题也可使用如下one-liner方法,比较直接