关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

力扣旋转字符串

发布时间:2023-06-27 00:00:28

一、轮转数组


题目链接:(来源于力扣)(右旋)


给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。


示例 1:


输入: nums = [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]


方法一:暴力解题:


一位一位的移动,用循环完成移动一位的操作,一次交换相邻两个数.


例如:右移一位


数据:1 2 3 4 5 6 7


图解:


 右移一位过程图:

   



//右移一位操作  for (i = numsSize - 1; i > 0; i--)  {  int tmp = nums[i];  nums[i] = nums[i - 1];  nums[i - 1] = tmp;  }

   


右移k位(外层加一个k次循环)


注意:如果移动的位数是数字个数的整数倍数,则相当于没有移动,用k%numsSize可以避免没有必要的多余循环.


void rotate(int* nums, int numsSize, int k)//外层循环 {  int i = 0;  k = k % numsSize;  while (k--)  {  for (i = numsSize - 1; i > 0; i--)//内部循环  {  //交换  int tmp = nums[i];  nums[i] = nums[i - 1];  nums[i - 1] = tmp;  }  } }

   


小改进:


将内部的每次循环都要创建变量进行交换,改成直接覆盖,将最后一位数字拷贝一份后,将前面的数据直接向后面覆盖,最后将首位数据赋值为拷贝的最后一位数值也可以完成操作.


图解:



代码:


void rotate(int* nums, int numsSize, int k) {  int i = 0;  k = k % numsSize;   while (k--)  {  int tmp = nums[numsSize - 1];//最后一位数字拷贝一份  for (i = numsSize - 1; i > 0; i--)//内部循环  {  nums[i] = nums[i - 1];//前面的数据直接向后面覆盖  }  nums[0] = tmp;//首位数据赋值为拷贝的最后一位数  }  }

   


但是,暴力解决,在面对大量的数据时,运行速度会慢很多,


 


方法二:三步翻转法.


其实有一个很神奇的现象,当我们需要右轮转 k 个位置时,可以将这个整形数组看作两部分


前半部分是:前n-k个数据,下标为[0,numsSize - k-1]


后半部分是:最后的k个数据,下标为:[numsSize - k,numsSize - 1]


然后分别逆序两部分,最后整体逆序就行了.


例如:数据1 2 3 4 5 6 7


逆序前半部分:4 3 2 1 5 6 7


逆序后半部分:4 3 2 1 7 6 5


逆序全部: 7 6 5 1 2 3 4



void reverse(int *arr,int left,int right) {  while(left<right)  {  int tmp = arr[left];  arr[left] = arr[right];  arr[right] = tmp;  left++;  right--;  } } void rotate(int* nums, int numsSize, int k){  if(numsSize==0)  {  return nums;  }  k = k % numsSize;  reverse(nums, 0, numsSize - k-1);//逆序前半部分  reverse(nums, numsSize - k, numsSize - 1);//逆序后半部分  reverse(nums, 0, numsSize - 1);//逆序整体 }

   


二.左旋转字符串


传送门:


题目描述:


一个给定的字符序列 S ,请你把其循环左移 K 位后的序列输出


示例1:


输入:


“abcXYZdef”,3


返回值:


“XYZdefabc”


学完上面的数组右旋,相信左旋字符串应该可以照猫画虎吧!


同理使用:三步翻转法


 #includevoid reverse(char *arr,int left,int right) {   while(left<right)  {  char tmp = arr[left];  arr[left] = arr[right];  arr[right] = tmp;  left++;  right--;  } } char* LeftRotateString(char* nums, int k ) {  int sz=strlen(nums);  if(sz==0)  {  return nums;  }  k = k % sz;  reverse(nums, 0, k-1);  reverse(nums, k, sz - 1);  reverse(nums, 0, sz - 1);  return nums; }

   


三:字符串旋转结果


题目描述:


自定义一个函数,要求判断一个字符串是否为另外一个字符串旋转之后的字符串。


要求这两个字符串长度相等.


返回值:


是: 返回1


不是:返回0.


示例1:


给定字符串s1 =AABCD和字符串s2 = BCDAA


s1左旋2个数后可以得到s2,所以结果为真,返回1;


示例2:


给定s1=abcd和s2=ACBD,


s1无法通过旋转得到,s2.结果为假,返回0;


思路一:


通过计算字符串长度得到sz,然后循环旋转sz次,每次旋转后与s2进行比较.


#include#include#includevoid reversed(char* left,char* right) {  assert(left);//防止传入空指针  assert(right);  while (left < right)  {  char tmp = *left;  *left = *right;  *right = tmp;  left++;  right--;  } } void left_revolve(char*arr,int k) {  int sz = strlen(arr);  k %= sz;  //逆序前k个  reversed(arr, arr+k-1);  //逆序后面剩下的  reversed(arr+k, arr+sz-1);  //逆序整体  reversed(arr, arr + sz - 1); } int is_revolve(char* s1, char* s2, int sz) {  int i = 0;  for (i = 0; i < sz; i++)  {  left_revolve(s1, 1);  if (strcmp(s1, s2) == 0)  {  return 1;  }  }  return 0; } int main() {  char s1[50] = { 0 };  char s2[50] = { 0 };  gets(s1);  gets(s2);  int sz = strlen(s1);  int ret = is_revolve(s1, s2, sz);  printf("%d", ret);  return 0; }

   


思路2:


创建一个临时字符数组(tmp),将s1字符串拷贝两份存入临时字符数组.


使用strstr函数,判断字符串s2是否为tmp的字串.


涉及库函数:


strcmp函数:字符串拷贝函数


strcat函数:字符串追加函数


strstr函数:查找子字符串函数.


这些字符串操作函数会在后续更新其使用方法,参数,以及模拟实现.


这些字符串操作函数会在后续更新其使用方法,参数,以及模拟实现.



#include#include#include#define Max 100//定义零时字符串的最大长度 int is_revolve(const char* s1, char* s2,int sz) {  assert(s1 && s2);  char tmp[Max];  strcpy(tmp, s1);//将字符串1拷贝一份放入零时数组中  strcat(tmp, s1);//使用字符串连接函数,将两个s1连接在一起  if (strstr(tmp, s2) != NULL)//如果strstr函数返回的地址不是NULL说明,含有子字符串.  {  return 1;  }  else 0;//否则没有子字符串.  } int main() {  char s1[50] = { 0 };//创建字符串s1  char s2[50] = { 0 };//创建字符串s2;  gets(s1);//获取字符串1  gets(s2);//获取字符串2  int sz = strlen(s1);//计算字符串长度  int ret = is_revolve(s1, s2, sz);  printf("%d", ret);  return 0; }

   



/template/Home/leiyu/PC/Static