文章:代码随想录
状态:多熟悉双指针
leecode 344 反转字符串
思路:这题比较简单,就是相向指针全部置换就行。
代码:
public void reverseString(char[] s) {
int right=s.length-1;
int left=0;
while (left<right){
s[right]^= s[left];
s[left]^=s[right];
s[right]^=s[left];
left++;
right--;
}
}
leecode 541 反转字符串ii
思路:
这里要明白,i的增长是2k的,然后根据每一次增长定义当前区间的范围。
代码:
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
int length=s.length();
for (int i = 0; i < ch.length; i+=2*k) {
int start=i;
int end=Math.min(start+k-1,length-1);
// int end=length-1-i<k?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);
}
LR122 路径加密
思路:
这题也比较简单,就是熟悉一下stringBuilder的使用。但是对于c++来说,可以直接给字符串进行扩容,然后用双指针从后往前,能把空间复杂度降为O1,对于java来说,字符串不可变,所以用stringbuilder进行拼接。
public String pathEncryption(String path) {
StringBuilder result=new StringBuilder();
for(char c : path.toCharArray()){
if(c =='.'){result.append(" ");}
else{result.append(c);}
}
return result.toString();
}
leecode 151 翻转单词
思路:
有两种思路:
第一种是用双指针从后往前遍历,然后去掉空格进行拼接再将结果记录到另一个字符串中。但是对于c++来说,这样空间复杂度就是0n了。所以有第二中思路可以让它变为O1.但是对于java来说都是On,因为java中字符串不可变。
第二种思路就是把这个过程分成三步:第一步先去除所有多余的空格,第二步就是翻转整个字符,第三步就是再对每一个单词进行翻转。对于去除多余空格,可以用同向双指针。这里和其实就和数组中移除元素题目的思想是一样的(移除空格),但是这里不能用相向指针,因为顺序不能打乱。
代码:
public static String reverseWords(String s) {
int m=s.length()-1;
while (s.charAt(m)==' '){m--;}
StringBuilder sb=new StringBuilder();
int n=m;
while (m>=0){
while (m>=0 && s.charAt(m)!=' '){m--;}
sb.append(s.substring(m+1,n+1)+" ");
while ( m>=0 && s.charAt(m)==' ')m--;
n=m;
}
return sb.toString().trim();
}
第二种:
public String reverseWords(String s) {
StringBuilder sb = trimSpaces(s);
// 翻转字符串
reverse(sb, 0, sb.length() - 1);
// 翻转每个单词
reverseEachWord(sb);
return sb.toString();
}
public StringBuilder trimSpaces(String s) {
int left = 0, right = s.length() - 1;
// 去掉字符串开头的空白字符
while (left <= right && s.charAt(left) == ' ') {
++left;
}
// 去掉字符串末尾的空白字符
while (left <= right && s.charAt(right) == ' ') {
--right;
}
// 将字符串间多余的空白字符去除
StringBuilder sb = new StringBuilder();
while (left <= right) {
char c = s.charAt(left);
if (c != ' ') {
sb.append(c);
} else if (sb.charAt(sb.length() - 1) != ' ') {
sb.append(c);
}
++left;
}
return sb;
}
public void reverse(StringBuilder sb, int left, int right) {
while (left < right) {
char tmp = sb.charAt(left);
sb.setCharAt(left++, sb.charAt(right));
sb.setCharAt(right--, tmp);
}
}
public void reverseEachWord(StringBuilder sb) {
int n = sb.length();
int start = 0, end = 0;
while (start < n) {
// 循环至单词的末尾
while (end < n && sb.charAt(end) != ' ') {
++end;
}
// 翻转单词
reverse(sb, start, end - 1);
// 更新start,去找下一个单词
start = end + 1;
++end;
}
}