编程之美2.17——数组循环移位

1、最简单的做法一位一位移,时间复杂度O(K*N)

string RightShift1(string &s, int n, int k)
{
	while(k--)
	{
		char c = s[n-1];
		for(int i = n - 1; i > 0; i--)
			s[i] = s[i-1];
		s[0] = c;
	}
	return s;
}

2、当K很大时,移动K位相当于移动  K%N 位O(N^2)

string RightShift2(string &s, int n, int k)
{
	k %= n;
	while(k--)
	{
		char c = s[n-1];
		for(int i = n - 1; i > 0; i--)
			s[i] = s[i-1];
		s[0] = c;
	}
	return s;
}

3、O(N)的做法

//对于abcd1234,若循环右移4位得到的1234abcd,
//可以看出有两部分是没有变的一部分是abcd,另一部分是1234
//所以可以通过以下三步完成循环移位:
//1、逆序排列abcd,得到dcba1234;
//2、逆序排列1234,得到dcba4321,
//3、逆序排列dcba4321,得到1234abcd;

void Reverse(string &s, int b, int e)
{
	for(; b < e; b++,e--)
	{
		char temp = s[e];
		s[e] = s[b];
		s[b] = temp;
	}
}

string RightShift3(string &s, int n, int k)
{
	k %= n;
	Reverse(s,0,n-k-1);
	Reverse(s,n-k,n-1);
	Reverse(s,0,n-1);
	return s;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值