344.反转字符串
参考文章:代码随想录
参考视频:字符串基础操作! | LeetCode:344.反转字符串_哔哩哔哩_bilibili
解题思路:双指针法,一个指向字符串第一个元素,一个指向最后一个元素,定义一个temp来存储字符,调换两个元素值,然后同时向中间移动一格,直到left>=right。
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
char temp = ' ';
while (left < right) {
temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
541. 反转字符串II
参考文章:代码随想录
参考视频:字符串操作进阶! | LeetCode:541. 反转字符串II_哔哩哔哩_bilibili
解题思路:以i+=2*k来去遍历字符串,反转i到i+k-1之间的字符,另外再对1+k大于数组长度做特殊处理。
public static String reverseStr(String s, int k) {
char[] arr = s.toCharArray();
for(int i =0;i<arr.length;i+=2*k){
if(i+k>arr.length){reverse(arr,i,arr.length-1);break;}
reverse(arr,i,i+k-1);
}
return new String(arr);
}
public static void reverse(char[] arr, int start, int end) {
char temp;
while (start < end) {
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
剑指Offer 05.替换空格
参考文章:代码随想录
解题思路:
解法1:首先遍历一遍字符串来计算字符串里的空格个数,然后new一个新的数组,存储大小为arr.length + count * 2,因为%20占三个字符,算上原本的空格需要多两个存储单位。第二遍再去遍历字符串,当遇到空格时用%20去替换,需要注意替换完成后指针的位置。
public static String replaceSpace(String s) {
char[] arr = s.toCharArray();
int count = 0;
for (char i : arr) {
if (i == ' ') {
count++;
}
}
char[] arr1 = new char[arr.length + count * 2];
int k = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == ' ') {
arr1[k] = '%';
arr1[k + 1] = '2';
arr1[k + 2] = '0';
k += 3;
continue;
}
arr1[k] = arr[i];
k++;
}
return new String(arr1);
}
解法2:定义一个新字符串str来存储需要的空格数,遍历原字符串,当遇到空格时新字符串str+=(两个空格),遍历完成后原字符串s+=str,将其转化为数组,然后用双指针,第一个作为快指针指向原字符串的最后一位,第二个为慢指针指向新字符串的最后一位,然后两个指针移动来去更新整个数组的元素。需要注意替换%20时,慢指针的下标改变。这么做优点为不需要再去申请一个新的存储空间了。
public static String replaceSpace1(String s) {
String str = "";
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ') {
str += " ";
}
}
int left = s.length() - 1;
s += str;
int right = s.length() - 1;
char[] chars = s.toCharArray();
while (left >= 0) {
if (chars[left] != ' ') {
chars[right] = chars[left];
right--;
left--;
}else{
chars[right] = '0';
chars[right-1] = '2';
chars[right-2] = '%';
right-=3;
left--;
}
}
return new String(chars);
}
151.翻转字符串里的单词
参考文章:代码随想录
参考视频:字符串操作进阶! | LeetCode:541. 反转字符串II_哔哩哔哩_bilibili
解题思路:这道题总共分三步。第一步先去将字符串多余的空格给删除。 第二步是翻转整个字符串。第三步将每个单词进行翻转。
- 移除多余空格 : "the sky is blue"
- 字符串反转:"eulb si yks eht"
- 单词反转:"blue is sky the"
public static String reverseWords(String s) {
char[] arr = s.toCharArray();
//删除多余空格
int slow = 0;
for (int fast = 0; fast < s.length(); fast++) {
if (arr[fast] != ' ') {
if (slow != 0) {
arr[slow++] = ' ';
}
while (fast < arr.length && arr[fast] != ' ') {
arr[slow] = arr[fast];
slow++;
fast++;
}
}
}
arr = Arrays.copyOf(arr, slow);
//反转整个字符串
reverseArray(arr, 0, arr.length - 1);
//反转每个单词
slow = 0;
for (int fast = 0; fast < arr.length; fast++) {
while (fast < arr.length && arr[fast] != ' ') {
fast++;
}
reverseArray(arr, slow, fast - 1);
slow = fast + 1;
}
return new String(arr);
}
public static void reverseArray(char[] arr, int start, int end) {
int left = start;
int right = end;
while (left < right) {
char temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
剑指Offer58-II.左旋转字符串
参考文章:代码随想录
解题思路:
解法1:可以发现原元素移动后下标变为了i-n+x(s.length()),因此可以申请一个新数组来存放移动后的元素。
public static String reverseLeftWords(String s, int n) {
char[] arr = s.toCharArray();
char[] arr1 = new char[arr.length];
for (int i = 0; i < arr.length; i++) {
int index = i - n;
while (index < 0) {
index += arr.length;
}
arr1[index] = arr[i];
}
return new String(arr1);
}
解法2:可以发现翻转前n个元素,再翻转n后面的元素,然后整体进行翻转即可达到左旋转字符串的效果。因此这道题就变得很容易了。
public static String reverseLeftWords1(String s, int n) {
char[] arr = s.toCharArray();
reverseArray(arr,0,n-1);
reverseArray(arr,n,arr.length-1);
reverseArray(arr,0,arr.length-1);
return new String(arr);
}
public static void reverseArray(char[] arr, int start, int end) {
int left = start;
int right = end;
while (left < right) {
char temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}