344 反转字符串
这题是这天几乎所有的基础,难度较低 思路:建立头尾指针,两两交换 代码:
public void reverseString(char[] s) {
int head = 0;
int tail = s.length - 1;
while (tail > head){
char temp = s[tail];
s[tail] = s[head];
s[head] = temp;
tail--;
head++;
}
}
541 反转字符串Ⅱ
方式一 无脑暴力硬写
public String reverseStr(String s, int k) {
char[] arr = s.toCharArray();
int head = 0;
int tail = 0;
// 冲突问题:k元素过大
// 1.当head已经指向最后元素,不能在再交换
// 2.当剩余不够2k但足够k
// 3.当剩余不够k
while (arr.length - 1 > tail) {
tail++;
if ((tail + 1) % (2 * k) == 0 || tail == arr.length - 1) {
// 交换前k个元素
// 避免k > length的情况
int head2 = Math.min(head + k - 1,arr.length - 1);
if (head == arr.length - 1) continue;
// 344 - 反转字符串
while (head2 > head) {
char temp = arr[head];
arr[head] = arr[head2];
arr[head2] = temp;
head2--;
head++;
}
head = tail + 1;
}
}
return new String(arr);
}
方式二 带脑子仔细思考 for循环,结合了while的条件以及最初的tail++,此写法的i = i + 2*k
更优化时间复杂度
public String reverseStr(String s, int k) {
char[] arr = s.toCharArray();
for (int i = 0; i < arr.length; i = i + 2*k) {
int head = i;
// 避免k > length的情况
int tail = Math.min(arr.length - 1,head + k - 1);
// 344 - 反转字符串
while (tail > head){
char temp = arr[head];
arr[head] = arr[tail];
arr[tail] = temp;
tail--;
head++;
}
}
return new String(arr);
}
剑指Offer 05.替换空格
难度较低 思路:遍历数组,有空格就替换(使用StringBuffer操作字符串)
public String replaceSpace(String s) {
if (s == null) return null;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' '){
sb.append("%20");
}
else {
sb.append(s.charAt(i));
}
}
return sb.toString();
}
151.翻转字符串里的单词
思路:
- 去掉多余空格(首尾 单词间)
- 反转字符串
- 翻转单词
public String reverseWords(String s) {
/*
* 思路:
* 1. 去掉多余空格(首尾 单词间)
* 2, 反转字符串
* 3, 翻转单词
* */
// 1. 去除空格
StringBuffer sb = removeSpace(s);
// 2. 反转字符串
reverseString(sb,0,sb.length() - 1);
// 3. 反转单词
reverseWord(sb);
return sb.toString();
}
// 功能:去除多余空格
public StringBuffer removeSpace(String s) {
// 去除首尾空格
int start = 0;
int end = s.length() - 1;
while (s.charAt(start) == ' ') start++;
while (s.charAt(end) == ' ') end--;
// 返回
StringBuffer sb = new StringBuffer();
while (end >= start) {
char c = s.charAt(start);
// 去除单词间多余空格
// 条件一:记录单词 条件二:记录空格
if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
sb.append(c);
}
start++;
}
return sb;
}
// 功能:344 - 反转字符串
public void reverseString(StringBuffer sb, int start, int end) {
while (end >= start) {
char c = sb.charAt(end);
sb.setCharAt(end,sb.charAt(start));
sb.setCharAt(start,c);
start++;
end--;
}
}
// 功能:反转单词
public void reverseWord(StringBuffer sb){
int start = 0;
int end = 1;
// 遍历整个句子
while (start < sb.length()){
// 寻找一个单词
while (end < sb.length() && sb.charAt(end)!=' '){
end++;
}
// 找到后 344 - 反转字符串(不反转空格)
reverseString(sb,start,end - 1);
start = end + 1;
end = start + 1;
}
}
剑指Offer58-II.左旋转字符串
思路:“负负得正”
- 先把前n个和后面元素分别反转,自然形成两组[-1,-2],然后全部一起反转变成[2,1],前n个数自然跑到后面
public String reverseLeftWords(String s, int n) {
// 思路:负负得正
// 先把前n个和后面元素分别反转,自然形成两组[-1,-2],然后全部一起反转变成[2,1],前n个数自然跑到后面
int len = s.length();
StringBuilder sb = new StringBuilder(s);
reverseString(sb, 0, n - 1);
reverseString(sb, n, len - 1);
return sb.reverse().toString();
}
public void reverseString(StringBuilder sb, int start, int end) {
while (start < end) {
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
}