所用代码 java
反转字符串 LeetCode 344
题目链接: 反转字符串 LeetCode 344 - 简单
思路
双指针直接交换左右两边的字符
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
// 取不取等都行,因为中间那个数不用交换
while (left < right){
// 交换
char temp = s[right];
s[right] = s[left];
s[left] = temp;
// 左右指针向中间靠拢
left++;
right--;
}
}
总结
取不取等不重要,中间那个数不用交换,记得每次操作后左右指针往中间移动一格就行了
反转字符串II LeetCode 541
题目链接:反转字符串II LeetCode 541 - 简单
思路
同第一个一样,只要找到要反转的部分进行反转就好了
public String reverseStr(String s, int k) {
char[] c = s.toCharArray();
for (int i = 0; i < c.length; i += 2*k) {
// 可以翻转k个字符就直接翻转,然后进行下一步
if (i+k < c.length){
swap(c,i,i+k-1);
}else {
// 否则就是不够k个字符了,直接翻转后面的字符
swap(c,i,c.length-1);
}
/*
// 剩余字符大于k个,小于2k个
if (i+2*k > c.length && i+k < c.length){
swap(c, i, i+k-1);
}else if(i+k > c.length){ // 剩余字符少于k个
swap(c,i,c.length-1);
}else {
swap(c,i,i+k-1);
}
*/
}
return String.valueOf(c);
}
// 指针所在位置反转,左闭右闭
public void swap(char[] s, int left, int right) {
while (left < right){
char temp = s[right];
s[right] = s[left];
s[left] = temp;
left++;
right--;
}
}
总结
注意每次循环是跳2k步
,每次再判断能不能在k的范围
内进行翻转。
剑指Offer 05.替换空格
题目链接:剑指Offer 05.替换空格 - 简单
思路
新建一个StringBuilder,一个一个的添加,遇到空格就添加%20
public String replaceSpace(String s) {
char[] c = s.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < c.length; i++) {
if (c[i] == ' '){
sb.append("%20");
continue;
}
sb.append(c[i]);
}
return sb.toString();
}
总结
java的StringBuilder用于添加字符非常的简单,如果使用双指针的话较为复杂,但是思想也很棒,没遇到一个空格,扩容两个空格位(就三个位置),这样就刚好可以存下 %20
left:指向原始数组的最后一个元素
right:指向扩容后数组的最后一个元素
双指针重要代码如下:
//有空格情况 定义两个指针
int left = s.length() - 1;//左指针:指向原始字符串最后一个位置
s += str.toString();
int right = s.length()-1;//右指针:指向扩展字符串的最后一个位置
char[] chars = s.toCharArray();
while(left>=0){
if(chars[left] == ' '){
chars[right--] = '0';
chars[right--] = '2';
chars[right] = '%';
}else{
chars[right] = chars[left];
}
left--;
right--;
}
翻转字符串里的单词 LeetCode 151
题目链接:翻转字符串里的单词 LeetCode 151 - 中等
思路
首先去掉首尾空格,然后反转整个字符串,再反转每个单词
public String reverseWords(String s) {
// 1、移除首尾和中间的空格
StringBuilder sb = removeSpace(s);
// 2、反转整个字符串
reverseString(sb,0, sb.length()-1);
// 3、反转各个单词
reverseEachWord(sb);
// 返回string
return sb.toString();
}
// 去除首尾空格
public StringBuilder removeSpace(String s){
StringBuilder sb = new StringBuilder();
int start = 0;
int end = s.length() - 1;
// 去除首部空格
while (s.charAt(start) == ' ') start++;
// 去除尾部空格
while (s.charAt(end) == ' ') end--;
while (start <= end){
char c = s.charAt(start);
// s的下一位不为空,或者下一个为空(单词直接的空格)但是不能有两个空格
if(c != ' ' || sb.charAt(sb.length()-1) != ' '){
sb.append(c);
}
start++;
}
// System.out.println("去除空格后的字符串:"+sb);
return sb;
}
// 反转整个StringBuilder (左闭右闭)
public void reverseString(StringBuilder sb,int start, int end){
while (start < end){
char temp = sb.charAt(start);
// sb.setCharAt(int i, "a") 设置i位置的值为a
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
// System.out.println("反转后的字符串"+sb);
}
// 反转其中的单词
public void reverseEachWord(StringBuilder sb){
int start = 0;
int end = 1;
while (start < sb.length()){
// 找到单词的末尾,末尾一定是空格,找到了之后end指向下一位(非空格位置)
while (end < sb.length() && sb.charAt(end) != ' '){
end++;
}
// 该方法为左闭右闭
reverseString(sb, start, end - 1);
// 反转完第一个单词,start与end往后移位
start = end + 1;
end = start + 1;
}
// System.out.println("单词反转:"+sb);
}
总结
本题知道方法,但是写不出来,看到题解,对各个方法也不是很熟,还要多学习理解各种写法!
剑指Offer58-II.左旋转字符串
题目链接:剑指Offer58-II.左旋转字符串 - 简答
思路
先把后面的数存到一个StringBuilder中,再把前面的数存到StringBuilder中
public String reverseLeftWords(String s, int n) {
StringBuilder sb = new StringBuilder();
char[] c = s.toCharArray();
// 先加后面几个数
for (int i = 0; i < c.length; i++) {
if (i<n){
continue;
}
sb.append(c[i]);
}
// 后加前面几个数
for (int i = 0; i < n; i++) {
sb.append(c[i]);
}
return sb.toString();
}
总结
看了代码随想录,是先将字符串整体反转,再分步反转,代码如下:
public String reverseLeftWords(String s, int n) {
char[] c = s.toCharArray();
int start = 0;
int end = c.length;
// 1、翻转整个字符串
reverse(c, start, end - 1);
// 2、翻转字符串n前面的buf
reverse(c, start, end - n - 1);
// 3、翻转字符串n后面的部分
reverse(c, end - n, end - 1);
return String.valueOf(c);
}
// 翻转字符串,左闭右闭
public void reverse(char[] c, int start, int end){
while (start < end){
char temp = c[end];
c[end] = c[start];
c[start] = temp;
start++;
end--;
}
}
这个操作的和就和前面的其他操作差不多,都是翻转字符串,重点就是:先整体后局部或者先局部后整体