day08 打卡344.反转字符串 剑指Offer 05.替换空格 151.翻转字符串里的单词 剑指Offer58-II.左旋转字符串
day08 打卡344.反转字符串 剑指Offer 05.替换空格 151.翻转字符串里的单词 剑指Offer58-II.左旋转字符串
344.反转字符串
1.看到不创建新的空间,就自然想到了下面的代码。
class Solution {
public void reverseString(char[] s) {
for (int i = 0, j = s.length-1; i<=j ; i++, j--) {
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
}
541. 反转字符串II
1.自己的思路:每次遍历到2k*n个,处理2k范围内的反转。循环结束后,再处理剩余的字符串。剩余的字符串有两种情况:
剩下字符<k,全部反转,right就是最后一个字符;
剩下字符>k,前k个反转,right就是left+k-1;
class Solution {
public String reverseStr(String s, int k) {
int i = 2*k;
int left = 0;
int right = 0;
char[] str = s.toCharArray();
for ( ; i<str.length ; i = i+2*k) {
left = i-2*k;
right = i-k-1;
str = reserve(str, left, right);
}
// 剩下的字符串处理,剩下的字符串肯定<2k
left = i-2*k;
if (str.length-left<k) {
// 剩下字符<k,全部反转
right = str.length-1;
str = reserve(str, left, right);
} else {
// 剩下字符>k,前k个反转
right = left+k-1;
str = reserve(str, left, right);
}
return new String(str);
}
public char[] reserve(char[] str, int left, int right) {
for (; left<=right ; left++, right--) {
char temp = str[right];
str[right] = str[left];
str[left] = temp;
}
return str;
}
}
2.看来代码随想录的视频,代码简洁了很多。不一样的思路,可以去看看视频
class Solution {
public String reverseStr(String s, int k) {
char[] str = s.toCharArray();
for (int i = 0 ; i<str.length ; i = i+2*k) {
// 满足大于或等于 k 个
if (i+k <= str.length) {
str = reserve(str, i, i+k-1);
continue;
}
// 处理剩余字符少于 k 个
str = reserve(str, i, str.length-1);
}
return new String(str);
}
public char[] reserve(char[] str, int left, int right) {
for (; left<=right ; left++, right--) {
char temp = str[right];
str[right] = str[left];
str[left] = temp;
}
return str;
}
}
剑指Offer 05.替换空格
1.最容易想到的
class Solution {
public String replaceSpace(String s) {
String result = "";
for (int i = 0 ; i<s.length() ; i++) {
char c = s.charAt(i);
if (c == ' ') {
result += "%20";
} else {
result += c;
}
}
return result;
}
}
2.看了视频,使用双指针的办法。先扩容(注意这里是找到的空格数量乘以2,我一开始写成了3)。再判断遇到的是否为空格。如果是空格,右指针-3,赋值% 2 0;否则,右指针-1,正常赋值。left每次都-1。
class Solution {
public String replaceSpace(String s) {
int count = 0;
for (int i = 0 ; i<s.length() ; i++) {
if (s.charAt(i) == ' ') {
count++;
}
}
if (count == 0) return s;
char[] str = new char[s.length() + 2*count];
int left = s.length()-1;
int right = str.length-1;
while(left>=0) {
char c = s.charAt(left);
if (c == ' ') {
str[right] = '0';
str[right-1] = '2';
str[right-2] = '%';
right = right-3;
} else {
str[right] = c;
right--;
}
left--;
}
return new String(str);
}
}
151.翻转字符串里的单词
1.反向遍历字符串。每当第一次遇到空格的时候,就说明了可以加入新的字符串了,字符串清空。如果连续空格,就continue,接着下次。
首先要把字符串的两端如果有空格,清空。所以i=0或者n-1的时候,都肯定不会是空格。空格最大就是n-2,最小就是1。
因为我们是倒着的,
怎么判断第一个空格呢?就是当前的等于空格并且前一个不是空格。
怎么判断是连续空格呢?先保证当前的是空格,后面的也等于空格就是需要跳过的。
class Solution {
public String reverseWords(String s) {
s = s.trim();
if (s == null || s.length() == 0) return s;
StringBuilder result = new StringBuilder();
String str = "";
for (int i = s.length()-1 ; i>=0 ; i--) {
char c = s.charAt(i);
if (i == 0 || (c == ' ' && s.charAt(i+1) != ' ')) {
if (i == 0) {
str = c + str;
} else {
str += " ";
}
result.append(str);
str = "";
continue;
}
if (c == ' ' && s.charAt(i+1) == ' ') {
continue;
}
str = c + str;
}
return result.toString();
}
}
2.看了代码随想录的修改
class Solution {
public String reverseWords(String s) {
// 1.去除首尾以及中间多余空格
StringBuilder sb = removeSpace(s);
// 2.反转整个字符串
reverseString(sb, 0, sb.length() - 1);
// 3.反转各个单词
reverseEachWord(sb);
return sb.toString();
}
public StringBuilder removeSpace(String s) {
int left = 0;
int right = s.length()-1;
StringBuilder sb = new StringBuilder();
while (s.charAt(left) == ' ') left++;
while (s.charAt(right) == ' ') right--;
while (left<=right) {
char c = s.charAt(left);
if (c == ' ' && s.charAt(left-1) == ' ') {
left++;
continue;
}
sb.append(c);
left++;
}
return sb;
}
public void reverseEachWord(StringBuilder sb) {
int start = 0;
int end = 1;
while (start<sb.length()) {
while (end<sb.length() && sb.charAt(end) != ' ') end++;
reverseString(sb, start, end-1);
start = end+1;
end = start+1;
}
}
// 反转字符串指定区间[start, end]的字符
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--;
}
}
}
剑指Offer58-II.左旋转字符串
1.不能申请额外空间的办法想不到,看了代码随想录的。
具体步骤为:
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder sb = new StringBuilder(s);
// 1. 反转前n个字母
reverseString(sb, 0, n-1);
// 2. 反转n到末尾的字母
reverseString(sb, n, s.length()-1);
// 3. 全部反转
reverseString(sb, 0, s.length()-1);
return sb.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--;
}
}
}

浙公网安备 33010602011771号