算法和数据结构是笔试和技术面必会涉及的内容,而且与编程有关最为基础也是最为重要的也是这一块,而目前笔记的题目往往是从公司的题库中抽取的,"猜中"的可能性还是比较大的,但如何去猜,并不是说我们上网把那什么面试宝典上的题全记一遍,但如果记性好,那也可以,比如那什么排序,查找考的可能性较大的,但是这样对于自己的思维上的提高真的帮助很小,这些天看算法和数据结构下来,发现很多的算法的思想方法是相通的,如果再了解如何去权衡时间复杂度和空间复杂度,如何优化自己的算法,这个过程才是最为重要的.
总结这些的学习,什么是符合题意的算法,网上基本都找的到,我觉得如果要记录下,最主要的是记录思考过程及思想方法.
PS.有些算法直接摘自网络,方便阅读.
什么左旋字体串,其它定义为把字符串前面若干个字符移动到字符串的尾部
设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),
且只允许使用两个附加变量。
如:
abcd1234→4abcd123→34abcd12→234abcd1→1234abcd。
这里的字符串的移动主要是通过字符交换完成.
这里我们可以发现其右移后的字符串和未移时的相比,可以明显的分段,即abcd和1234,两子段的顺序没有变化.
这里我们给出一个思路,因为循环右移的整体感觉就是两个子段的交换位置
法一,常用的方法是:先将子段逆顺,然后再整体逆序.
我们可以这样理解,反反得正.即我们最终换的只是子段的位置,而不改变子段的顺序,而我们先将子段逆序,再整体逆序最终结果是子段内顺序的还原,
用数学表示
1、首先分为俩部分,X:abc,Y:def;
2、X->X^T,abc->cba, Y->Y^T,def->fed。
3、(X^TY^T)^T=YX,cbafed->defabc,即整个翻转。
#include<string.h>
#define offset 3
void reverse(char *array,int b,int e);
int main()
{
int i=0;
char array[11]="abcde12345";
int len=strlen(array);
reverse(array,0,offset); //左移位数
reverse(array,offset+1,len-1);
reverse(array,0,len-1);
for(i=0;i<len;i++){
printf("%c",array[i]);
}
printf("\n");
return 0;
}
void reverse(char *array,int b,int e){
for(;b<e;b++,e--){
array[b]^=array[e];
array[e]^=array[b]; //这是不用辅助变量的交换方法,主要的原理是x^y^y=x;y^x^x=y;
array[b]^=array[e];
}
}
#define M 4
void reverse(char *array,int length,int m);
void swap(char *a,char *b);
int main(){
char array[]="abcdefghijkljk";
int len=strlen(array);
reverse(array,len,M);
int i;
for(i=0;i<len;i++){
printf("%c",array[i]);
}
printf("\n");
return 0;
}
void swap(char *a,char *b){
*a^=*b;
*b^=*a;
*a^=*b;
}
void reverse(char *array,int length,int m){
int p1=0,p2=m;
int k=(length/m-1)*m;
while(k--){
swap(array+p1,array+p2);
p1++;
p2++;
}
int r=length%m; //乘下的字符个数
while(r--){
int i=p2;
while(i>p1){
swap(array+i,array+i-1);
i--;
}
p1++;
}
}
总结: