目录
344 反转字符串
541 反转字符串II
剑指Offer 05 替换空格
151 翻转字符串里的单词
剑指Offer58-II 左旋转字符串
题目链接
看到题目的第一想法:使用双指针直接交换首尾元素,而后两指针分别向右和向左移动。
代码实现:
public void reverseString(char[] s) {
int length = s.length;
int left = 0;
int right = length - 1;
//char ch;
while (left < right) {
//交换left,right元素
//调用reverse函数没有改变顺序,应该是函数没有返回的问题?-->>
//原因应当是你传入的知识字符,并不知道是数组,就是未将反转的元素与数组相关联
//需要将数组也传进去才行,然后跟着一起变化
reverse(s, left, right);
/*ch = s[left];
s[left] = s[right];
s[right] = ch;*/
left++;
right--;
}
}
public void reverse(char[] s, int i, int j) {
char ch = s[i];
s[i] = s[j];
s[j] = ch;
}
实现过程中遇到哪些困难
题目链接
看到题目的第一想法:我的思路是,字符串长度len分别对2k做求余数和求商的操作,然后分别处理前2ki中以2k为步进值得前k部分,而后对余数判断与k的大小关系,而后分别进行处理,但是处理的很混乱,导致无法ac,后续再看看。
我的代码
public String reverseStr(String s, int k) {
int length = s.length();
if (length < k) {
return s;
}
int yushu = length % (2 * k);
int times = length / (2 * k);
String str = "";
for (int i = 0; i < times; i++) {
//substring而非subString
String si = s.substring(2 * k * i, (2 * i + 1) * k);
str += reverse(si, k);
str += s.substring((2 * i + 1) * k, (2 * i + 2) * k);
}
if ( yushu > 0 && yushu < k) {
str += reverse(s.substring(yushu), yushu);
}else if (yushu >= k && yushu < 2 * k) {
str += reverse(s.substring(length - yushu, length - yushu + k), k);
str += s.substring(length - yushu + k);
}
return str;
}
//按照指定长度反转字符串
public String reverse(String str, int l) {
//l >= 1
char[] ch = str.toCharArray();
int len = ch.length;
if (l > len) {
l = len;
}
int left = 0;
int right = l - 1;
while (left < right) {
char temp = ch[left];
ch[left] = ch[right];
ch[right] = temp;
left++;
right--;
}
return new String(ch);
}
看完代码随想录之后的想法:卡哥给出的思路和代码就很清晰,每隔2k个元素反转前k个,若不够则全部反转
卡哥的代码实现:
public String reverseStr(String s, int k) {
//自己的思路:2nk内的部分,每次反转前k个,而后判断剩余的元素与k的关系,代码比较复杂,也未能ac
//卡哥的思路:每隔2k个元素反转前k个,若不够则全部反转
char[] ch = s.toCharArray();
int length = ch.length;
for (int i = 0; i < length; i += 2 * k) {
int start = i;
//根据尾数够不够k个来判断end的位置
int end = Math.min(length - 1, start + k - 1);
while (start < end) {
ch[start] ^= ch[end];
ch[end] ^= ch[start];
ch[start] ^= ch[end];
start++;
end--;
}
}
return new String(ch);
}
}
实现过程中遇到哪些困难:
for (int i = 0; i < length; i += 2 * k) {
int start = i;
//根据尾数够不够k个来判断end的位置
int end = Math.min(length - 1, start + k - 1);
题目链接
看到题目的第一想法:因为这道题之前做过,看到题之后知道要对字符串进行加长,但StringBuilder的使用不熟练,创建,设置值等。
看完代码随想录之后的想法:双指针法也很实用,实现时比单纯使用StringBuilder更加复杂,在对字符串进行扩容的时候,需要注意的是,字符串应当在尾部扩容,而并非在遇到空格直接扩容(加空格)。
代码实现:
public String replaceSpace(String s) {
/*//使用stringbuilder更简单
int len = s.length();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.length(); i++) {
if(' ' == s.charAt(i)) {
sb.append("%20");
} else {
sb.append(s.charAt(i));
}
}
return sb.toString();*/
//另外一种方法是双指针
int len = s.length();
StringBuilder sb = new StringBuilder();
sb.append(s);
//应当先在字符串的最后扩容,不能遇到空格就扩容,因为前len个字符不可变化
for(int i = 0; i < len; i++) {
if(' ' == s.charAt(i)) {
//此处需要注意
sb.append(" ");
}
}
if(sb.length() == len) {
return s;
}
String str = sb.toString();
char[] ch = str.toCharArray();
int left = len - 1;
int right = ch.length - 1;
while (left >= 0) {
if (ch[left] == ' ') {
ch[right--] = '0';
ch[right--] = '2';
ch[right--] = '%';
//ch[right] = '%';
}else {
ch[right--] = ch[left];
//ch[right] = ch[left];
}
left--;
//right--;
}
return new String(ch);
}
实现过程中遇到哪些困难:
题目链接
看到题目的第一想法:看到题目的时候有思路,但是实现不了,需要加强练习,还有就是方法何时有返回值,何时用void还不太清楚。
看完代码随想录之后的想法:卡哥的代码很清晰,自己在消除中间多余空格时不会处理;sb的setCharAt()未使用过。
代码实现:
public String reverseWords(String s) {
//太费劲了,比着写都有很多错的,什么时候方法用void,什么时候有返回值都需要注意
//去除首尾的空格,去除中间连续的多个空格
//完全反转字符串
//反转每个单词
StringBuilder sb = removeSpace(s);
reverseWholeString(sb, 0, sb.length() - 1);
reverseEachWord(sb);
return sb.toString();
}
public StringBuilder removeSpace(String s){
int left = 0;
int right = s.length() - 1;
//去除首尾的空格
while (left <= right && s.charAt(left) == ' ') {
left++;
}
while (right >= left && s.charAt(right) == ' ') {
right--;
}
//去除中间的空格
StringBuilder sb = new StringBuilder();
while(left <= right) {
char c = s.charAt(left);
if(c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
sb.append(c);
}
left++;
}
return sb;
}
public void reverseWholeString(StringBuilder sb, int left, int right) {
while (left < right) {
char temp = sb.charAt(left);
sb.setCharAt(left, sb.charAt(right));
sb.setCharAt(right, temp);
left++;
right--;
}
//此方法是否有返回值
/*char[] ch = s.toCharArray();
int length = ch.length;
//int left = 0;
//int right = length - 1;
while (left < right) {
char temp = ch[left];
ch[left] = ch[right];
ch[right] = temp;
left++;
right--;
}
s = new String(ch);*/
}
public void reverseEachWord(StringBuilder s) {
//char[] ch = s.toCharArray();
//后面一个字符为空格时,反转前方单词
int left = 0;
int right = 1;
int length = s.length();
while(left < length){
while (right < length && s.charAt(right) != ' '){
right++;
}
reverseWholeString(s, left, right - 1);
left = right + 1;
right = left + 1;
}
}
实现过程中遇到哪些困难:
while(left <= right) {
char c = s.charAt(left);
if(c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
sb.append(c);
}
left++;
题目链接
看到题目的第一想法:看到题目后有思路,先完全反转,而后反转后n个,然后反转前len-n个。
看完代码随想录之后的想法:卡哥的方法中,方法没有返回值的时候一般使用stringbuilder,可以原地操作字符串;当然也可以有返回值string,稍微麻烦一点。
代码实现:
我的思路:有返回值
public String reverseLeftWords(String s, int n) {
//将元素反转,而后后面n个元素反转,前面s.length()-n个元素也反转
s = reverseString(s, 0, s.length() - 1);
s = reverseString(s, 0, s.length() - n - 1);
s = reverseString(s, s.length() - n, s.length() - 1);
return s;
}
public String reverseString(String s, int left, int right) {
char[] ch = s.toCharArray();
while(left < right) {
char temp = ch[left];
ch[left] = ch[right];
ch[right] = temp;
left++;
right--;
}
return new String(ch);
}
卡哥的方法:无返回值
public String reverseLeftWords(String s, int n) {
//将元素反转,而后后面n个元素反转,前面s.length()-n个元素也反转
//使用StringBuilder()后面函数的返回值可以为void
//sb操作其中的部分值时比较方便
StringBuilder sb = new StringBuilder(s);
reverseString(sb, 0, sb.length() - 1);
reverseString(sb, 0, sb.length() - n - 1);
reverseString(sb, sb.length() - n, sb.length() - 1);
return sb.toString();
}
public void reverseString(StringBuilder s, int left, int right) {
//char[] ch = s.toCharArray();
while(left < right) {
char temp = s.charAt(left);
s.setCharAt(left, s.charAt(right));
s.setCharAt(right, temp);
left++;
right--;
}
}
实现过程中遇到哪些困难:
今日收获,记录一下自己的学习时长