您的位置:首页 > 其它

一道百度试题

2011-08-10 20:38 260 查看
有一串首尾相连的珠子,共有m个,每一个珠子有一种颜色,并且颜色的总数不超过n(n<=10),求连续的珠子的颜色总数为n时,长度最小的区间。可简述思路或者给出伪代码,并且给出时间和空间复杂度分析。(baidu 2011校园招聘笔试题目)

只能求出一个解来,很难做到最优解。

思路是:

1.将串换为一个个的集合,每一个集合为一组相邻且不重复的颜色组成。(这里颜色用数组表示)

2.依据集合中颜色数目的多少插入到Beadinfo数组中。

3.将不同集合中的Bit进行与操作,如果为OKOK,则说明两个集合中的颜色组合可以为n。

目前,在useassemble中仅仅将不同颜色最多的集合与别的集合进行合并查看,如果找到就返回区间距离,这种做法不能保证找到最小区间,甚至也不能保证能找到一个颜色总数为n的区间。

//有100个珠子
#define TOTAL 30
#define CORLOR	6
char OKOK = ((0x01<<1)|(0x01<<2)|(0x01<<3)|(0x01<<4)|(0x01<<5)|(0x01<<6));

int Bead[TOTAL];

struct info{
char num;	//有几个连续的相等
char bit;	//缺失那一个?
short start;//在Bead数组中的开始位置
};

struct info Beadinfo[TOTAL];
int infosize = 0;

void getBead(){
int i;
srand( (unsigned)time( NULL ) );
for(i = 0; i < TOTAL; i++){
Bead[i] = rand()%CORLOR + 1;
printf("%d  ", Bead[i]);
}
}

void init_Breadinfo(){
int i;
for(i = 0; i < TOTAL; i++){
Beadinfo[i].start = -1;
}
}
//插入排序法,最大的放在最前
void insertBeadinfo( struct info a ){
int i = 0;
int j = 0;
//if( Beadinfo[0].start == -1 ){
//	Beadinfo[0] = a;
//	infosize++;
//	return ;
//}
while( i< infosize ){
if(a.num>Beadinfo[i].num)
break;
i++;
}
for(j = infosize -1;j !=i-1;j--){
Beadinfo[j+1] = Beadinfo[j];
}
Beadinfo[i] = a;
infosize++;
}

void preassemble(int *a, int size){
int i = 0;
int* pre = a;
int* tail = a;
struct info tmp;
tail++;
while( tail < a + size ){
tmp.start = pre - a;
tmp.bit = 0x01<<(*pre);
while( (tmp.bit & 0x01<<*tail) == 0 && ( tail < a + size ) ){
tmp.bit |= 0x01<<(*tail);
tail++;
}
tmp.num = tail - pre;
insertBeadinfo(tmp);
//Beadinfo[infosize++] = tmp;
while(*pre!=*tail)pre++;
pre++;
tail = pre+1;
}
//因为是环形,所以让首位相接  暂不考虑
//tail = a + size - 1;
//if( *tail == *a )
//	return ;
//tmp = Beadinfo[0];
//while( (tmp.bit & 0x01<<*tail) == 0 ){
//	tmp.bit |= 0x01<<(*tail);
//	tail--;
//}
//tmp.num += a + size - tail -1;
//tmp.start = tail - a + 1;
//insertBeadinfo(tmp);
}

void viewassemble(){
int i;
printf("\nbeadinfo:\n");
for(i = 0; i < infosize; i++){
printf("start:%d , num%d\n", Beadinfo[i].start, Beadinfo[i].num);
}
}

int useassemble(){
int i = 0;
char bit = 0;
int j,k;
for( k = 0; k<infosize-1;k++){
for( i=k; i < infosize-1; i++ ){
if( (Beadinfo[k].bit|Beadinfo[i+1].bit) ==OKOK ){
if( Beadinfo[i+1].start > Beadinfo[k].start ){
j = Beadinfo[k].start;
while( bit!=OKOK ){
bit |= 0x01<<Bead[j];
j++;
}
printf("start at %d end at %d", Beadinfo[k].start, j-1);
j -= Beadinfo[k].start;
return j > (TOTAL-j)?(TOTAL-j):j;
}
else{
j = Beadinfo[k].start + Beadinfo[k].num -1;
if( j > TOTAL){
//这里也可能出现错误
}else{
while( bit!=OKOK ){
bit |= 0x01<<Bead[j];
j--;
}
printf("start at %d end at %d", j+1, Beadinfo[k].start + Beadinfo[k].num -1);
j = Beadinfo[k].start + Beadinfo[k].num - j -1;
return j > (TOTAL-j)?(TOTAL-j):j;
}
}
}
}
}
}

int main(int argc, char **argv)
{
int num = TOTAL;
getBead();
init_Breadinfo();
preassemble(Bead, num);
viewassemble();
useassemble();
return 0;
}


程序运行结果大致为:

2  1  3  1  4  4  5  1  3  3  5  1  1  5  5  6  2  1  5  2  5  4  6  1  6  4  5  5  5  5
beadinfo:
start:19 , num5
start:5 , num4
start:14 , num4
start:15 , num4
start:23 , num4
start:0 , num3
start:2 , num3
start:9 , num3
start:17 , num3
start:12 , num2
start:27 , num1
start:28 , num1
start at 9 end at 23


其中的
start:19 , num5  即对应数组中的:2 5 4 6 1
start at 9 end at 23,即在这一串中包含了所有颜色:
3  5  1  1  5  5  6  2  1  5  2  5  4  6  1


如果你对实现很感兴趣,可以参考:

http://www.spongeliu.com/%E7%AE%97%E6%B3%95/baidu2011/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: