算法跟学Day8【代码随想录】
大纲 字符串专题
● 344.反转字符串
● 541. 反转字符串II
● 剑指Offer 05.替换空格
● 151.翻转字符串里的单词
● 剑指Offer58-II.左旋转字符串
leetcode 344
反转字符串
思路
- 交换反转
细节
- 交换次数为数组长度的向下取整
代码
class Solution {
public void reverseString(char[] s) {
int len = s.length;
for (int i = 0; i < len >> 1; i++) {
char tmp = s[i];
s[i] = s[len - i - 1];
s[len - i - 1] = tmp;
}
}
}
复杂度
- 时间
O(n)
- 空间
O(1)
leetcode 541
反转字符串II
思路
- 每隔k个数就反转 也就是反转和不反转总和为2k, 设置循环步长2k, 每次处理当前2k中的待反转字符
细节
- 注意边界条件
代码
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i += 2 * k)
if (i + k < ch.length) reverse(ch, i, i + k - 1);
else reverse(ch, i, ch.length - 1);
return new String(ch);
}
public void reverse(char[] ch, int i, int j) {
while (i < j) {
char tmp = ch[i];
ch[i++] = ch[j];
ch[j--] = tmp;
}
}
}
复杂度
- 时间
O(n)
- 空间
O(n)
剑指Offer 05
替换空格
思路
- 创建一个辅助数组用来存储最终字符串的字符
- 注意最终数组的大小精确控制需要扫描一遍字符串得到其中空格字符的个数
细节
- 使用双指针逐字母填入
代码
class Solution {
public String replaceSpace(String s) {
int len = s.length(), count = s.length();
for (int i = 0; i < len; i++) if (s.charAt(i) == ' ') count += 2;
char[] res = new char[count];
for (int i = 0, j = 0; i < len; i++)
if (s.charAt(i) == ' ') {
res[j++] = '%';
res[j++] = '2';
res[j++] = '0';
} else res[j++] = s.charAt(i);
return new String(res);
}
}
复杂度
- 时间
O(n)
- 空间
O(n)
复杂度
- 时间
- 空间
leetcode 151
翻转字符串里的单词
思路
- 将每个单词逐一记录 再逆序输出
细节
- 注意使用双指针来定位一个单词
代码
class Solution {
public String reverseWords(String s) {
List<String> list = new ArrayList<>();
for (int i = 0, j = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ' && s.charAt(j) == ' ') { // 去前导0
j++;
continue;
}else if (s.charAt(i) == ' ') { // 双指针已指向一个完整单词
list.add(s.substring(j, i));
j = i;
}
// 将j指向一个新单词的开头
if(i > 0 && s.charAt(i) != ' ' && s.charAt(i - 1) == ' ')
j = i;
if (i == s.length() - 1 && s.charAt(i) != ' ')
list.add(s.substring(j, s.length()));
}
StringBuilder sb = new StringBuilder();
for (int i = list.size() - 1; i >= 0 ; i--) {
sb.append(list.get(i));
if (i != 0) sb.append(" ");
}
return sb.toString();
}
}
复杂度
- 时间
O(n)
- 空间
O(n)
剑指Offer58-II
左旋转字符串
思路
- 反转前i个 反转后i个 再反转整个
细节
- 注意进厂时机
代码
class Solution {
public String reverseLeftWords(String s, int n) {
char[] ch = s.toCharArray();
reverse(ch, 0, n - 1);
reverse(ch, n, s.length() - 1);
reverse(ch, 0, s.length() - 1);
return new String(ch);
}
public void reverse(char[] ch, int i, int j) {
while (i < j) {
char tmp = ch[i];
ch[i++] = ch[j];
ch[j--] = tmp;
}
}
}
复杂度
- 时间
O(n)
- 空间
O(n)