左旋转字符串

题目:左旋转字符串,定义字符串的左旋转操作:把前面若干个字符移动到尾部。比如把"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位的图形演示:


左旋转字符串_第1张图片


算法实现:

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;
			}	
		}
	}
}

另一种方法:
与翻转句子中的单词顺序类似,假设左旋转count位,令count等于count除以n取余,先翻转整个字符串,再翻转前n-count个字符和后count个字符。或者先翻转前count个字符与后n-count个字符,然后翻转整个字符串。

算法实现:

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;
		reverseStr(str);//翻转整个字符串
		temp=str[n-count];//保存翻转前n-count个字符的后一个字符
		str[n-count]='\0';
		reverseStr(str);//翻转前n-count个字符
		str[n-count]=temp;//恢复翻转前n-count个字符的后一个字符
		reverseStr(str+n-count);//翻转后count个字符
	}
}


reverseStr()方法在我的一篇博文中有具体的实现:字符串翻转


拓展:类似的读者可以自己尝试实现一下字符串的右旋转。当然也可以把右旋转转换成左旋转,假设字符串右旋转count位,令count等于count除以n取余,然后让字符串左旋转n-count位。

你可能感兴趣的:(旋转,左旋转,旋转字符串,左旋转字符串,旋转字符)