题目链接:344. 反转字符串
思路:让第一个和最后一个交换位置,第二个和倒数第二个交换位置,依次类推。
时间复杂度O(n)
,空间复杂度O(1)
class Solution {
public void reverseString(char[] s) {
// 一左一右两个指针相向而行
int left = 0, right = s.length - 1;
while (left < right) {
// 交换 s[left] 和 s[right]
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
// public void reverseString(char[] s) {
// int len = s.length;
// for(int left = 0, right = len - 1; left < right; left++, right--){
// char temp = s[left];
// s[left] = s[right];
// s[right] = temp;
// }
// }
}
这里交换数据的时候也可以通过位运算来交换。
class Solution {
public void reverseString(char[] s) {
int l = 0;
int r = s.length - 1;
while (l < r) {
s[l] ^= s[r]; //构造 a ^ b 的结果,并放在 a 中
s[r] ^= s[l]; //将 a ^ b 这一结果再 ^ b ,存入b中,此时 b = a, a = a ^ b
s[l] ^= s[r]; //a ^ b 的结果再 ^ a ,存入 a 中,此时 b = a, a = b 完成交换
l++;
r--;
}
}
}
题目链接:541. 反转字符串II
思路:反转的思路和反转数组一样,就是交换前面和后面的数据。本题重点要对反转的边界条件进行判断。
时间复杂度O(n)
// 题目的意思其实概括为 每隔2k个反转前k个,尾数不够k个时候全部反转
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i = i + 2 * k) {
int start = i;
// 判断尾数够不够k个来取决end指针的位置
int end = Math.min(ch.length - 1, start + k - 1);
while (start < end) {
char temp = ch[start];
ch[start] = ch[end];
ch[end] = temp;
start++;
end--;
}
}
return new String(ch);
}
}
题目链接:剑指Offer 05. 替换空格
思路:开辟新的空间来进行赋值操作,这样的话实现十分简单。
时间复杂度O(n)
class Solution {
public String replaceSpace(String s) {
StringBuffer res = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ')
res.append("%20");
else
res.append(s.charAt(i));
}
return res.toString();
}
}
题目链接:151. 翻转字符串里的单词
思路:使用split()按照空格分割,然后再倒序拼接。
时间复杂度O(n)
class Solution {
public String reverseWords(String s) {
String[] strs = s.trim().split(" "); // 删除首尾空格,分割字符串
StringBuilder res = new StringBuilder();
for (int i = strs.length - 1; i >= 0; i--) { // 倒序遍历单词列表
if (strs[i].equals("")) continue; // 遇到空单词则跳过
res.append(strs[i] + " "); // 将单词拼接至 StringBuilder
}
return res.toString().trim(); // 转化为字符串,删除尾部空格,并返回
}
}
提高本题的难度:不要使用辅助空间,空间复杂度要求为O(1)。
题目链接:剑指Offer58-II. 左旋转字符串
思路:开辟新的数组,对数组进行赋值操作,同样实现比较简单但意义不大。
时间复杂度O(n)
,空间复杂度O(n)
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuffer res = new StringBuffer();
for(int i = n; i < s.length(); i++){
res.append(s.charAt(i));
}
for(int i = 0; i < n; i++){
res.append(s.charAt(i));
}
return res.toString();
}
}
更简单做法:
class Solution {
public String reverseLeftWords(String s, int n) {
return s.substring(n) + s.substring(0, n);
}
}
代码随想录上的方法,先对前k个元素进行反转,然后再对后面的元素进行反转,最后对所有元素进行反转,就能够得到目标值。时间复杂度O(n)
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder sb = new StringBuilder(s);
reverseString(sb, 0, n - 1);
reverseString(sb, n, s.length() - 1);
reverseString(sb, 0, s.length() - 1);
return sb.toString();
}
private void reverseString(StringBuilder s, int start, int end) {
while (start < end) {
char temp = s.charAt(start);
s.setCharAt(start, s.charAt(end));
s.setCharAt(end, temp);
start++;
end--;
}
}
}