目录
在力扣或者牛客网这些OJ刷题平台经常能够看到一些题目,要求你将字符串逆置或者旋转字符串、亦或者旋转数组。那今天就跟大家讲解一下逆置算法。首先我们来学习一下逆置字符串。
思路: | |
逆置字符串,循环的方式实现非常简单 | |
1. 给两个指针,left放在字符串左侧,right放在最后一个有效字符位置 | |
2. 交换两个指针位置上的字符 | |
3. left指针往后走,right指针往前走,只要两个指针没有相遇,继续2,两个指针相遇后,逆置结束 |
代码示例:
- #include
- #include
-
- void reverse_string(char* arr)
- {
- char *left = arr;
- char *right = arr+strlen(arr)-1;
-
- while(left
- {
- char tmp = *left;
- *left = *right;
- *right = tmp;
-
- left++;
- right--;
- }
- }
-
- int main()
- {
- char arr[] = "joyy";
- reverse(arr);
- printf("%s\n", arr);
- return 0;
- }
-
-
- #include
- #include
- void reverse_string(char* arr)
- {
- int len = strlen(arr);
- int i = 0;
- for (i = 0; i < len / 2; i++)
- {
- char temp = *(arr + i);
- *(arr + i) = *(arr + len - 1 - i);
- *(arr + len - 1 - i) = temp;
- }
- }
- int main()
- {
- char arr[] = "joyy";
- reverse_string(arr);
- printf("%s\n", arr);
- return 0;
- }
递归版本
递归方式:
对于字符串“abcdefg”,递归实现的大概原理:
1. 交换a和g,
2. 以递归的方式逆置源字符串的剩余部分,剩余部分可以看成一个有效的字符串,再以类似的方式逆置
代码示例:
- #include
- #include
-
- void reverse_string(char* arr)
- {
- int len = strlen(arr);
- char tmp = *arr;
- *arr = *(arr+len-1);
-
- *(arr+len-1) = '\0';
- if(strlen(arr+1)>=2) //判断条件改为strlen(arr+1)>0也行
- reverse_string(arr+1);
-
- *(arr+len-1) = tmp;
- }
-
- int main()
- {
- char arr[] = "joyy";
- reverse_string(arr);
- printf("%s\n", arr);
- return 0;
- }
注意:上面循环的两个版本思路差不多,使用while循环的实现方式是通过指针加加减减来实现交换,而for循环的实现方式是通过下标的方式来堆成交换。 然后递归版本最需要注意的点就是:将*(str+len-1)赋给*arr后,一定要将*(str+len-1)改为'\0'以减小字符串的长度,否则无法实现递归。
旋转数组
示例:给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]
暴力求解法
分析:
代码示例:
- #include
- void rotate(int* nums, int numsSize, int k)
- {
- k %= numsSize;
- for (int i = 0; i < k; i++)
- {
- int temp = nums[numsSize - 1];
- for (int k = numsSize - 2; k >= 0; k--)
- {
- nums[k + 1] = nums[k];
- }
- nums[0] = temp;
- }
-
-
- }
-
- int main()
- {
- int arr[] = { 1,2,3,4,5,6,7 };
- rotate(arr, 7, 10);
- for (int i = 0; i < 7; i++)
- {
- printf("%d ", arr[i]);
- }
- return 0;
- }
这种方法还是比较容易想到的方法,但是它不是最优的方法。接下来,博主给大家介绍一种更加优的方法。
反转法
分析:
反转法主要涉及了三次逆置:第一次是前n-k个元素逆置,第二次是后k个元素逆置,第三次是整个数组逆置。所以反转法需要借助上面已经介绍到了的逆置算法。
代码示例:
- void rotate(int* nums, int numsSize, int k)
- {
- k %= numsSize;
- //前n-k个元素逆置
- reverse(nums, 0, numsSize - k - 1);
- //后k个元素逆置
- reverse(nums, numsSize - k, numsSize - 1);
- //整个数组逆置
- reverse(nums, 0, numsSize - 1);
-
- }
-
- int main()
- {
- int arr[] = { 1,2,3,4,5,6,7 };
- rotate(arr, 7, 3);
- for (int i = 0; i < 7; i++)
- {
- printf("%d ", arr[i]);
- }
- return 0;
- }
以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以给个三连支持一下!谢谢大家啦!
结语
每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根。