在对字符串进行反转操作时,要使时间复杂度为O(n),那么就需要在本串上操作,也就是双指针法。
模板
使用此模板后,只需要在反转的区间做做文章。
public char[] reverse(char[] array, int left, int right) {for (; left < right; left++, right--) {char temp = array[left];array[left] = array[right];array[right] = temp;}return array;}
541.反转字符串 II
其实在遍历字符串的过程中,只要让 i += (2 k),i 每次移动 2 k 就可以了,然后判断是否需要有反转的区间。
public String reverseStr(String s, int k) {char[] array = s.toCharArray();int i = 0;for (; i < array.length; i += 2 * k) {if (i + k <= array.length) {array = reverse(array, i, i + k - 1);continue;}array = reverse(array, i, array.length - 1);}return new String(array);}public char[] reverse(char[] array, int left, int right) {for (; left < right; left++, right--) {char temp = array[left];array[left] = array[right];array[right] = temp;}return array;}
151.翻转字符串里的单词
不要使用辅助空间,空间复杂度要求为O(1)。
不能使用辅助空间之后,那么只能在原字符串上下功夫了。
想一下,我们将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,单词不就正过来了。
所以解题思路如下:
- 移除多余空格
 - 将整个字符串反转
 将每个单词反转 ```java class Solution { /**
* 水题做法** @param s* @return*/
/* public String reverseWords(String s) {
String[] strings = s.trim().split(" ");StringBuffer stringBuffer = new StringBuffer();for (int k = strings.length - 1; k >= 0; k--) {if (strings[k] != "") {if (k > 0) {stringBuffer.append(strings[k]).append(" ");} else {stringBuffer.append(strings[k]);}}}return String.valueOf(stringBuffer);
}
*/
public String reverseWords(String s) {
// 去除首尾空格StringBuilder sb = removeSpace(s);// 反转所有字符reverseString(sb, 0, sb.length() - 1);// 反转其中单词reverseEachWord(sb);return String.valueOf(sb);
}
/**
* 去掉空格** @param s* @return*/
private StringBuilder removeSpace(String s) {
StringBuilder sb = new StringBuilder();int start = 0, end = s.length() - 1;// 去掉首尾空格while (s.charAt(start) == ' ') start++;while (s.charAt(end) == ' ') end--;while (start <= end) {// 不存在空格追加进去char c = s.charAt(start);if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {sb.append(c);}start++;}return sb;
}
/**
* 反转字符串指定区间[start, end]的字符** @param sb* @param start* @param end*/
public void reverseString(StringBuilder sb, int start, int end) {
for (; start < end; start++, end--) {char temp = sb.charAt(start);sb.setCharAt(start, sb.charAt(end));sb.setCharAt(end, temp);}
}
/*** 反转每个单词** @param sb*/private void reverseEachWord(StringBuilder sb) {int start = 0, 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;}}
}
<a name="cgPJE"></a># 剑指Offer58-II.左旋转字符串这道题目也非常类似,依然可以通过局部反转+整体反转 达到左旋转的目的。<br />具体步骤为:1. 反转区间为前n的子串1. 反转区间为n到末尾的子串1. 反转整个字符串```javaclass Solution {public String reverseLeftWords(String s, int n) {s = reverse(s, 0, n - 1);s = reverse(s, n, s.length() - 1);s = reverse(s, 0, s.length() - 1);return s;}public String reverse(String s, int i, int j) {char[] chars = s.toCharArray();for (; i < j; i++, j--) {char temp = chars[i];chars[i] = chars[j];chars[j] = temp;}return String.valueOf(chars);}}
