【July程序员编程艺术】之字符串左旋

本文探讨了如何在保持时间复杂度为O(n)、空间复杂度为O(1)的前提下,实现字符串的左旋转操作。通过改进的迭代方法,避免了使用额外内存空间,详细解释了关键步骤和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

我的解题思路:
1.最简单的思路
拿到这个题目,如果不考虑时间复杂度和空间复杂度的要求,那么我的首选思路是:建立一个缓存数组存储要左旋的字符(如题中的ab),然后直接从c开始,每个字符覆盖左移两个位置的字符(c->a,d->b这样)。最后再把ab依次放到数组的最后。这种思路非常简单,时间复杂度是o(n),但是空间复杂度是o(m),不合题意。
2.改进的思路
由于题目要求空间复杂度为O(1),因此是无法使用额外的内存空间,自然想到必须要通过交换操作而不是覆盖操作来实现旋转。接下来就可以想到博客中所提到的思路二,具体的细节不再多说,自己编写程序如下:

#include <string>
#include <iostream>
using namespace std;
void shift(string & src,int n,int cnt);
void swap(char * a,char * b );
void main()
{

    string src("abcdefghijk");
    int cnt=3;
    //string result; 
    int n=src.length();
    shift(src,n,cnt);
    cout << "result is " << src <<endl;
    getchar();
}

void shift(string & src,int n,int cnt)
{
    char * spoint = &(src[0]);
    char * dpoint = spoint+cnt;
  while(n>cnt)
 {
    if(2*cnt<=n)
    {
        for(int i=0;i<cnt;i++)
            swap(spoint+i,dpoint+i);
    }
    else
    {
        int r = spoint+n-dpoint;
        for(int j=0;j<r;j++)
        {

            for(int i=cnt+j;i>j;i--)
            {
            swap(spoint+i,spoint+i-1);

            }
        }
    }
    n=n-cnt;
    spoint=spoint+cnt;
    dpoint=dpoint+cnt;
  }
}

void swap(char * a,char * b )
{
    char tmp;
    tmp=*a;
    *a=*b;
    *b=tmp;
}

在思考上述问题的时候,也发现可以使用递归的方法去做。对本题而言,递归和循环的思路并无太多区别,都是重复同一种操作而已。

之后的思路四只能用精彩形容。
思路五很奇妙。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值