算法通关村第十二关——字符串经典基础面试题(白银)
1 反转的问题
1.1 反转字符串
这道题没什么好说的
class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while(left < right){
char temp = s[left];
s[left++] = s[right];
s[right--] = temp;
}
}
}
1.2 反转字符串 II
这道题比较烦的就是逻辑处理这块:
- 如果剩余字符少于
k
个,则将剩余字符全部反转。 - 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。
class Solution {
public String reverseStr(String s, int k) {
int n = s.length();
char[] arr = s.toCharArray();
for (int i = 0; i < n; i += 2 * k) {
reverse(arr, i, Math.min(i + k, n) - 1);
}
return new String(arr);
}
public void reverse(char[] arr, int left, int right) {
while (left < right) {
char temp = arr[left];
arr[left++] = arr[right];
arr[right--] = temp;
}
}
}
i 表示当前要进行反转的子字符串的起始位置。由于每次要反转的子字符串包括前 k 个字符,因此起始位置为 i。
Math.min(i + k, n) - 1 用来确定子字符串的结束位置。
-
其中,i + k 表示子字符串的最大可能结束位置,n 是原始字符串的长度。
-
如果 i + k 的值小于 n,则说明当前子字符串的长度不足 k,可以直接取 i + k 作为结束位置。
-
否则,即 i + k >= n,说明当前子字符串的长度超过等于 k,应该只取到 n - 1 作为结束位置,以保证不越界。
1.3 仅仅反转字母
这道题就是最简单的反转字符串多了一个判断
class Solution {
public String reverseOnlyLetters(String s) {
int left = 0;
int right = s.length() - 1;
char[] ch = s.toCharArray();
while (left < right) {
if (!Character.isLetter(ch[left])) {
left++;
} else if (!Character.isLetter(ch[right])) {
right--;
} else {
char temp = ch[left];
ch[left++] = ch[right];
ch[right--] = temp;
}
}
return new String(ch);
}
}