1: 设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),
且只允许使用两个附加变量。既 abcd1234,右移k=4位,变为1234abcd
#include<iostream>
using namespace std;
//---------------------------------------
//方式1,每次右移动1位,时间复杂度为O(m*N)
void RightShift(char *s,int k)
{
int len = strlen(s);
int m = k%len;
while (m--)
{
char tempc = s[len -1];
for (int i = len - 2; i >=0; i--)
{
s[i+1] = s[i];
}
s[0] = tempc;
}
}
//-----------------------------------------
//方式2:利用求逆
//1、首先分为俩部分,X:abc,Y:def;
//2、X->X^T,abc->cba, Y->Y^T,def->fed。
//3、(X^T,Y^T)^T=YX,cbafed->defabc,即整个翻转。
void reverse(char *s,int begin,int end)
{
for (;begin<end;begin++,end--)
{
char tempc = s[begin];
s[begin] = s[end];
s[end] = tempc;
}
}
void RightShift2(char *s,int k)
{
int len = strlen(s); //abcdef123456, XY
int m = k%len;
reverse(s,0,len - m - 1);
reverse(s,len - m,len-1);//654
reverse(s,0,len-1);
}
int main()
{
char s[] = "abcde12345";
RightShift(s,5);
printf("%s\n",s);
RightShift2(s,7);
printf("%s\n",s);
system("pause");
return 0;
}
STL rotate算法:
1:gcd原理
公约数:30的约数为1,2,3,5,6,10.15.30., 24的约数为:1,2,3,4,6,12,14,则30和24的公约数为1,2,3,6
gcd(a,b)=gcd(b,a mod b)(a非负,b为正整数)
公约数的重要性质为:d|a(d为a的约数)并且d|b,则d|(a+b),并且d|(a-b),更一般为d|a.d|b蕴含d|(ax+by);(x,y为整数)
则此证明很简单,gcd(a,b)|gcd(b,a MOD b), 假设 d = gcd(a,b),则d|a,d|b, 又a MOD b = a – qb(q= a/b),既根据以上性质有d|(a MOD b)
gcd(b,a MOD b)|gcd(a,b),和以上证明类似 d|b,d|(a MOD b), a = qb+(a MOD b) (q = a/b),既a为b和(a MOD b)的线性组合,则d|(qb+(a MOD b)),既d|a, 则有 d|b,和d|a,所以gcd(a,b)|gcd(b,a MOD b);
——————————————————-
相关问题1:循环移位后是否包含
相关问题2:一个字符串中的所有字母,是否被另外一个字符串完全包含
位图法:
#include<iostream>
#include<bitset>
using namespace std;
#define SHIFT 5
#define N 26
#define MASK 0x01f
#define WORDLEN 32
int a[N/WORDLEN+1];
void setbit(int i)
{
a[i>>SHIFT] |= 1<<(i&MASK);
}
void clearbit(int i)
{
a[i>>SHIFT] &= ~(1<<(i&MASK));
}
int test_i(int i)
{
return a[i>>SHIFT] & (1<<(i&MASK));
}
char s1[] = "AABCDEFCDEFGMLNOP";
char s2[] = "CDAAEFGMNOP";
int main()
{
int str1len = strlen(s1);
int str2len = strlen(s2);
for(int i = 0; i < str2len; i++)//较短的字符串设置bit
{
int m = (int)(s2[i] - 'A');
setbit(m);
}
cout<<bitset<26>(a[0])<<endl;
for (int i = 0; i < str1len; i++)//较长的字符串清除bit
{
int m = (int)(s1[i] - 'A');
clearbit(m);
}
cout<<bitset<26>(a[0])<<endl;
if(a[0] == 0)cout<<"str2 的所有字母在str1中"<<endl;//26位,没有位置1
system("pause");
return 0;
}