题目:左旋转字符串,定义字符串的左旋转操作:把前面若干个字符移动到尾部。比如把"lavor_zl"左旋转3位得"or_zllav"。要求时间对长度为n的字符串操作复杂度为O(n),辅助内存为O(1)。
解题思路:
定义一个整型参数count,用它表示旋转的位数,当左旋转的位数大于等于字符串长度时,可以用它除以字符串长度求余来表示旋转的位数,因为左旋转字符串长度的整数倍,字符串保持不变。这题有两个限制:辅助内存为O(1),那么我们就不可以用一个长度为n的数组来按照要求保存所有字符,再把它赋给原字符串;时间复杂度为O(n),那么我们在移动一块count个字符和另一块n-count个字符的时候,我们不能每次旋转1位,否则需要旋转count位,而旋转一位的时间复杂度是O(n),那么旋转count位时间复杂度可能是O(n*n)。我们可以令p等于count,q等于n-count,如果p小于等于q时,将p中所有字符与q中的后p个字符进行交换,然后判断p是否与q相等,如果是直接返回,字符串左旋转完成,否则令q等于q-p;如果p大于q,将p中的后q个字符与q中的所有字符交换。一直执行下去,直到判断p是否与q相等时,p与q相等,并返回。
将字符串"lavor_zl"坐旋转3位的图形演示:
算法实现:
void leftRotateStr(char str[],int count) { if(str==NULL||str[0]=='\0'||str[1]=='\0') return;//字符串为空或为空串或长度为1时无需旋转 int n=0;//用来记录字符串的长度 while(str[n]!='\0') { n++; } count=count%n; if(count==0) return;//字符串旋转字符串长度的整数倍,与不旋转的结果是一样的 else if(count<0) { printf("count不可以为负数"); return; } else { char temp;//辅助存储 int p=count; int q=n-count; while(true) { if(p<=q) { for(int i=0;i<p;i++) { //交换 temp=str[i]; str[i]=str[q+i]; str[q+i]=temp; } if(p==q) break; q=q-p; } else { for(int i=p-q;i<p;i++) { //交换 temp=str[i]; str[i]=str[q+i]; str[q+i]=temp; } p=p-q; } } } }
原文地址:http://blog.csdn.net/lavor_zl/article/details/42716889