名人效应(空间优化)

名人:所有人都认识名人,名人不认识其他任何人

//由题目可判断出,名人最多只有一个,反证:若存在两个名人,则不符合

法一:穷举   O(n^2)

法二:O(n)    空间:O(n)

思路:若A认识B,那么A一定不是名人

代码:

int findstar()
{
    for(int i=0;i<n;i++)//n为人数
        a[i]=i;
    while(n>1){
        if(known(a[0],a[1]))
            a[0]=a[--n];
        else
            a[1]=a[--n];
    }
    for(int i=0;i<n;i++){
        if(a[0]!=i&&(known(a[0],a[i])||!known(a[i],a[0])))
            return -1;
    }
    return a[0];
}
法三:

空间优化  空间O(1)  一头扫

int findstar()
{
    int star=0;
    for(int i=1;i<n;i++)
        if(known(star,i))
           star=i;
    return star;
}
法四:空间优化  空间O(1)  两头扫

int findstar()
{
    int top=0,tail=n-1;
    while(top>tail){
        if(known(top,tail))
            top++;
        else if(known(tail,top))
            tail--;
    }
    return top;
}

老师:

/* 名人问题:有n个人他们之间认识与否用邻接矩阵表示(1表示认识,0表示不认识),
并且A认识B并不意味着B认识A,名人定义为他不认识任何人,且所有人都认识他。请求出所有名人 */
分析:只有一个名人(反证法) 

方案一:穷举 O(n^2)

方案二:o(n) 空间o(n)) 
	 for (int i=0;i<n;i++)
   			a[i]=i;              //没检查过的人
		 while (n>1)) {
		 	if (known[a[0],a[1]]) a[0]=a[--n];    //删除认识的人  a[i]=a[--n] 
		 	else a[1]=a[--n];
		 }
		 for (int i=0;i<n;i++)
		 	if (a[0]) != i)&&(known[a[0]][i]||!known[i][a[0]]])
		 	    return -1;
		 	    
		return a[0];
		
方案三:空间优化  空间o(1) 一头扫
       i<j [0...i-1]没有名人,  [i...j-1] 没有名人  
       若i认识j,删除i :i=j,j=j+1
	     i不认识j,删除j:j=j+1 
	    int i=0,j=1;	  
		for (;j<n;++j) { if (known[i][j]) i =j; }
		for (j=0;j<n;++j) {
			if ((i!=j)&&(known[i][j]||!known[j][i])) return -1; //没有名人 
		}
		return i; 
方案四: 空间优化  空间o(1) 两头扫
		i=0,j=n-1
		i<j [0...i-1]没有名人,  [j+1...n-1] 没有名人
		若i认识j,删除i :++i
		 i不认识j,删除j:--j
		 int i=0,j=n-1;
		 while (i<j) 
		     if known[i][j] ++i;
		     else --j;
		 for (j=0;j<n;++j) {
			if ((i!=j)&&(known[i][j]||!known[j][i])) return -1; //没有名人
		return i;





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值