您的位置:首页 > 其它

左旋转字符串(字符串)

2013-08-27 00:41 169 查看
左旋转字符串(字符串)题目:定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。如把字符串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

这个相对于第一种方法太好编码了就略了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: