左旋转字符串(字符串)

左旋转字符串(字符串)题目:定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数。要求时间对长度为n的字符串操作的复杂度为O(n),辅助内存为O(1)。


思路: 由于两个要求,导致编码很麻烦了, 思路就是成段的和相邻的字符交换

abcdef 2

那么就用ab 和 cd交换变成 cdabef

再用ab和 ef交换 变成 cdefab ,就完成了


但是出现abcdefg 3

abc 和def 交换变成 defabcg

但是这个时候abc 和g没法交换了, 那么我们就反着旋转就ok了, 比如 让g 和 c交换变成 abgc

g 和b交换变成agbc, 

g和a交换变成gabc;就达到目的了


编码的时候注意交换的方向随着能否交换而不停的改变


abcdef 2

第一次remain = (6 - 2) - 2 = 2

最终当remain == 0的时候停止循环就行了


#include <cstring>
#include <cstdio>

using namespace std;

template<class T>
void swap(T &x, T &y)
{
	char tmp;
	tmp = x;
	x = y;
	y = tmp;
}
void leftToRight(char s[], int start, int len)
{
	for(int i = start; i < len + start; i++)
	{
		swap(s[i], s[i + len]);
	}
}
void rightToLeft(char s[], int start, int len)
{
	for(int i = start; i > start - len; i--)
		swap(s[i], s[i - len]);
}

int solve(char s[], int m)           // O(1)的空间复杂度,o(n)的时间复杂度, 旋转字符串
{
	const int len = strlen(s);
	int remain = len - m;

	int i = 0;
	bool dir = true;    //朝右
	while(remain)
	{
		if(dir)
		{
			if(m <= remain)
			{
				remain -= m;
				leftToRight(s, i, m);
				i += m;
			}
			else
			{
				dir = !dir;
				i = i + m + remain - 1;
				swap(m, remain);
			}
		}
		else
		{
			if(m <= remain)
			{
				remain -= m;
				rightToLeft(s, i, m);
				i -= m;
			}
			else
			{
				dir = !dir;
				i = i - remain - m + 1;
				swap(m, remain);
			}
		}
	}
	for(int i = 0; i < len; i++)
		printf("%c", s[i]);
	puts("");
	return 0;
}

int main()
{
	char s[] = "abcdefgabcdeft";
	solve(s, 4);
	return 0;
}


当我写完程序后发现时间空间复杂度多了m, 更不好的是编码麻烦; 然后我就发现网上有一个更牛逼的解法


abcdef 2

第一步: ba

第二步: fedc

然后见可以bafedc

最后就cdefab



这个相对于第一种方法太好编码了就略了



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值