算法面试-学习笔记-左旋转字符串

来源:互联网 发布:c语言socket长链接 编辑:程序博客网 时间:2024/05/17 23:54

学习来自 程序员编程艺术(算法卷):第一章、左旋转字符串

先说一一下题目描述:例如 abcdefg 如果向右侧旋转3 变成 efgabcd 显然算法可以通过一个一个的右移来实现,时间复杂度是 K*N,N是字符串长度,K是移动的个数

我们的目的是要找到一个时间复杂度为N并且空间复杂度是1的算法

(有一处感觉怪怪,他为什么 K = K%N 后就说复杂度是 N^2了,雾水,我怎么觉得应该是 K%N * N)哈哈

思考 abcdefg 右移动3位 那么最后的格局是 efg一定跑前面去了 abcd efg 割开,最后的结果啊 efg  abcd,如果翻转结果串为 dcba gfe 观察发现就是 abcd efg两个各自翻转的结果,所以算法总结为:

假设右旋转 K 则

1. a0,a1...an-k-1  翻转

2. an-k, .. an-1 翻转

3. a0....an-1翻转

他有个更好的解释

对于这个问题,咱们换一个角度可以这么做:
将一个字符串分成两部分,X和Y两个部分,在字符串上定义反转的操作X^T,即把X的所有字符反转(如,X="abc",那么X^T="cba"),那么我们可以得到下面的结论:(X^TY^T)^T=YX。显然我们这就可以转化为字符串的反转的问题了。

自己写的程序如下:

#include <stdio.h>#include <string.h>void swap(char *pA,char *pB){char tmp = *pA;*pA = *pB;*pB = tmp;}void reverse(char *pArray,int f,int t){while(f<t){swap(pArray+f++,pArray+t--);}}int main(){char str[100];int nShift,nLen;while(scanf("%s%d",str,&nShift) != EOF){nLen = strlen(str);nShift = nShift % nLen;reverse(str,0,nLen-nShift-1);reverse(str,nLen-nShift,nLen - 1);reverse(str,0,nLen-1);printf("%s\n",str);}}

原创粉丝点击