344.反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
思路: 双指针法
有for和while两种实现方式
都是将首尾的值互换, 左右指针一同内移, 重复操作.
注:要控制好跳出循环的条件
代码实现:
/**
* for
*/
public void reverseString(char[] arr) {
int n = arr.length - 1;
char temp;
for (int i = 0; i < arr.length / 2; i++) {
temp = arr[i];
arr[i] = arr[n];
arr[n] = temp;
n--;
}
}
/**
* while
*/
public void reverseString(char[] s) {
int l = 0;
int r = s.length - 1;
while(l < r){
char temp = s[l];
s[l] = s[r];
s[r] = temp;
l++;
r--;
}
}
541. 反转字符串II
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例 1:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
示例 2:
输入:s = "abcd", k = 2
输出:"bacd"
思路: 双指针法
题目有点拗口, 大抵意思为最开始k位反转, 接下来的k位不反转, 再接下来的k位反转…
实现方式以 344.反转字符串 为基础, 区别在于需要分段反转.
此时也需要左右指针对分段反转的部分进行控制:
左指针起始点为0, 每次循环+2k, 则右指针为 左指针+k-1
依次类推…
代码实现:
public String reverseStr(String s, int k) {
char[] chars = s.toCharArray();
int length = chars.length;
for (int l = 0; l < length; l += 2 * k) {
int r = l + k - 1;
reverse(chars, l, Math.min(r, length - 1));
}
return String.valueOf(chars);
}
private void reverse(char[] chars, int l, int r) {
while (l < r) {
char c = chars[l];
chars[l] = chars[r];
chars[r] = c;
l++;
r--;
}
}
剑指Offer 05.替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1:
输入:s = "We are happy."
输出:"We%20are%20happy."
思路: StringBuilder
在遍历字符串时, 将字符串数据转移至 StringBuilder , 若遇到空格则用 %20 代替
代码实现:
public String replaceSpace(String s) {
StringBuilder sb = new StringBuilder();
for (char c : s.toCharArray()) {
if (c == ' ') {
sb.append("%20");
} else {
sb.append(c);
}
}
return sb.toString();
}
151.翻转字符串里的单词
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
输入:s = "the sky is blue"
输出:"blue is sky the"
示例 2:
输入:s = " hello world "
输出:"world hello"
解释:反转后的字符串中不能存在前导空格和尾随空格。
示例 3:
输入:s = "a good example"
输出:"example good a"
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。
思路: 双指针
倒序遍历字符串, 确定空格与字母的分割线, 左指针指向分割线r, 右指针指向上次分割时左指针的位置, 每次到达分割位置时, 读取左右指针之间的字符到StringBuilder中(非空格), 而后再补上空格, 依次类推…
代码实现:
public String reverseWords(String s) {
StringBuilder sb = new StringBuilder();
char[] charArray = s.toCharArray();
int left = s.length();
int right = left;
while (left-- > 0) {
if (charArray[left] != ' ' && (left == 0 || charArray[left - 1] == ' ')) {
for (int i = left; i < right; i++) {
char c = charArray[i];
if (c != ' ') {
sb.append(c);
}
}
right = left;
sb.append(" ");
}
}
return sb.toString().trim();
}
其他思路
剑指Offer58-II.左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
示例 1:
输入: s = "abcdefg", k = 2
输出: "cdefgab"
示例 2:
输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
思路:
将要左旋的字符缓存到一个新的数组中去, 将原数组左移, 再将缓存写入原数组后面的位置.
代码实现:
public String reverseLeftWords(String s, int n) {
char[] charArray = s.toCharArray();
char[] buffer = new char[n];
System.arraycopy(charArray, 0, buffer, 0, n);
for (int i = 0; i < charArray.length - n; i++) {
charArray[i] = charArray[n + i];
}
System.arraycopy(buffer, 0, charArray, charArray.length - n, n);
return new String(charArray);
}