在用c++写着点东西,但是这两天看了看面试题,网上的微软面试100题之类的,发现自己的基础还是很差的。做了5道之后就感觉力不从心了,于是希望自己通过看这个方面的资料,写点东西,每天一点点的坚持吧。
看了这个博客http://blog.csdn.net/v_july_v/article/details/6460494总结得挺好的。
1、定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
如把字符串abcdef左旋转2位得到字符串cdefab。
请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1)。
看到这个题目想到的方法就是直接取前两位再取后几位,然后把前面的两位放到最后去就OK了。于是写下代码
#include<iostream> #include "string.h" char* leftRevolve(char *arr,char*dst,int k); int main() { char a[]="abcdefghijk"; char d[]="abcdefghijk"; char * ps = leftRevolve(a,d,3); for(;*ps!='\0';ps++) std::cout<<*ps; std::cout<<std::endl; ps=NULL; return 0; } char *leftRevolve(char * arr,char * dst,int k) { char*p=arr;//定义指针指向数组的起始位置。 char*q=dst;//放入参数中,目的是为了方便初始化。 int len =strlen(arr);//获得字符串长度 if(k>len)//如果k大于n是k取k%n { k%=len; } p+=k;//从第三个开始 int i=len-k; while (i--) { *(q++)=*(p++); } p=arr;//定义指针指向数组的起始位置。 while (k--) { *(q++)=*(p++); } *(q++)='\0'; return dst; }
好了,测试完了之后,看了下那面的那个博客。写出了其它几种思路。另外右移位数K大于N的时候,K值为k%n。
1、每次将数组中的元素右移一位,循环K次。
如:abcd1234→4abcd123→34abcd12→234abcd1→1234abcd。
2、变换的过程通过以下步骤完成:
逆序排列abcd:abcd1234 → dcba1234;
逆序排列1234:dcba1234 → dcba4321;
全部逆序:dcba4321 → 1234abcd。
3、通过反转1、首先分为俩部分,X:abc,Y:def;
2、X->X^T,abc->cba, Y->Y^T,def->fed。
3、(X^TY^T)^T=YX,cbafed->defabc,即整个翻转。
4、如果abcdef ghij要变成defghij abc:
abcdef ghij
1. def abc ghij
2. def ghi abc j //接下来,j 步步前移
3. def ghi ab jc
4. def ghi a j bc
5. def ghi j abc
5、通过递归
设原始问题为:将“123abcdefg”左旋转为“abcdefg123”,即总长度为10,旋转部("123")长度为3的左旋转。按照思路二的运算,演变过程为“123abcdefg”->"abc123defg"->"abcdef123g"。这时,"123"无法和"g"作对调,该问题递归转化为:将“123g”右旋转为"g123",即总长度为4,旋转部("g")长度为1的右旋转。
6、stl::rotate 算法的步步深入
重点说下这个算法,这个在july的博客中讲的很清楚了,很佩服他能把一个算法上的问题扩展这么多,也行这个深度还谈不上科研,但是这个深度对于一般的程序员来说,是绰绰有余了。
这边我理解还不是很深入,先写到这。