1.题目描述
描述
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列 S ,请你把其循环左移 K 位后的序列输出。例如,字符序列 S = ”abcXYZdef” , 要求输出循环左移 3 位后的结果,即 “XYZdefabc”
数据范围:输入的字符串长度满足 0 \le len \le 100 \0≤len≤100 , 0 \le n \le 100 \0≤n≤100
进阶:空间复杂度 O(n)\O(n) ,时间复杂度 O(n)\O(n)
示例1
输入:
"abcXYZdef",3
复制返回值:
"XYZdefabc"
复制
示例2
输入:
"aab",10
复制返回值:
"aba"
https://www.nowcoder.com/share/jump/1889476041706625158356 题目链接放这里啦~
2.方法一(元素一一挪)
2.1算法解析
由上图我们可以发现左移6次和左移1次后的结果相同,所以我们可以用n%len来表示字符串左移的元素个数,那我们该怎么左移呢~
下面我用图像来表示核心算法~
2.2代码实现
下面是在牛客上解题的完整代码~
char* LeftRotateString(char* str, int n) { if(str==NULL) return NULL; int len=strlen(str); if(len==0) return str; int time=n%len; if(time==0) return str;//不用处理,返回原数组即可 for (int i = 0; i < time; i++) { int tmp = str[0]; int j = 0; for (; j < len - 1; j++) { str[j] = str[j + 1]; } str[j] = tmp; } return str; }
3.方法二(三次逆置)
3.1算法解析
废话不多说,直接上图啦~
怎么样,算法是不是很简单呢~
3.2代码实现
void Reverse(char str[], int start,int end) { while (start < end) { int tmp = str[start]; str[start] = str[end]; str[end] = tmp; start++; end --; } }//部分逆置函数 char* LeftRotateString(char* str, int n) { int len=strlen(str); if(len==0)//没有这个判断,编不过去 return str; int k=n%len; Reverse(str,0,k-1); Reverse(str,k,len-1); Reverse(str,0,len-1); return str; }
4.方法三(库方法)
4.1算法解析
再讲具体算法前,这里要先介绍俩个库函数(strcpy,strcat)
. strcpy
. strcat
下面就是这种算法的图解啦~
4.2代码实现
char* LeftRotateString(char* str, int n) { if(NULL==str) return NULL; int size=strlen(str); if(size==0) return str;//这里换成NULL就不能通过 int k=n%size; char*tmp=(char*)malloc(sizeof(char)*2*size);//动态内存开辟俩倍空间 strcpy(tmp,str); //我们下意识的这里也同样使用strcpy但是这会存在问题。 //因为strcpy会拷贝‘\0’,导致输出的函数可能缺少一部分,而strcat会覆盖‘\0’。 strcat(tmp,str); tmp[k+size]='\0'; return tmp+k; }