旋转字符串的三种算法

来源:互联网 发布:jre 8u25 windows x64 编辑:程序博客网 时间:2024/05/22 11:23

题目:给定一个长度为n的字符串,将它向左旋转i个位置,例如,str = "abcdefg", n = 7, i = 3,则旋转后,str = "defgabc",要求空间复杂度为1。

一般,解旋转字符串这样的题目,最简单的做法即是先将前i个字符拷贝到临时空间,然后将后n - i个字符前移,最后再将临时空间中的数据拷贝到原字符串的后i个位置上。但这样做会额外浪费i个空间。现给出如下三种算法:

• 算法一:

void swap(char* str, int n, int ){                                                                                                                     int j;    for (j = 0; j < i; ++j) {        int t = str[j];        str[j] = str[n - i + j];        str[n - i + j] = t;    }}void rotate(char* str, int n, int i) {        if (0 == i || n == i)        return;    int k = n - i;    if (i < k) {        swap(str, n, i);        rotate(str, n - i, i);    }    else {        swap(str, n, k);        rotate(str + k, n - k, i - k);    }}
算法二:

void reverse(char*str, int n) {    int m = n / 2;    int i;    for (i = 0; i < m; ++i) {        int t = str[i];        str[i] = str[ n - 1 - i];        str[n - 1 - i] = t;    }}void rotate(char* str, int n, int i) {    reverse(str, i);    reverse(str + i, n - i);    reverse(str, n);}

算法三:

int gcd(int m, int n) {     int k = m % n;    if (0 == k)        return n;    else        return gcd(n, k);}void rotate(char* str, int n, int i) {    int k = gcd(n, i);    int init;    for (init = 0; init < k; ++init) {                int cur = init;        char t = str[cur];        int next;        for (next = (cur + i) % n; next != init; next = (cur + i) % n) {            str[cur] = str[next];            cur = next;        }           str[cur] = t;    }}

不难看出,这三种算法的空间复杂度都是1,而时间复杂度都是n。但,算法三实际上更加巧妙,它所用时间只是前两者的一半。



1 0
原创粉丝点击