1. 找明星

给定一个房间,有n个人。判断是否存在这样一个人,房间内的所有其他人都认识他,但是他不认识其他的所有人。给定API:know(i, j), 如果为true的话,就表示i认识j,如果为false的话就表示i不认识j。

思路:
当know(i, j)值为true的时候,表示i认识j,则i肯定不是明星;

当know(i, j)值为false的时候,表示i不认识j,则j肯定不是明星。

因此每调用一次know(i, j)的值,我们就可以判断出,其中有一个人不是明星。最多调用n次就可以得到结果,时间复杂度为O(n)。当最后只剩下一个人的时候,不代表这个人一定是明星,通过上述方法,只能保证排除掉的不是明星,但不能保证,剩下的就是明星。所以最后还要遍历一次数组,确认最终剩下的人是否是明星。

方法1:建立一个哈希表将0~n-1存入表中,每当排除一个人不是明星,我们就将这个元素从表中删掉,直到最后表中剩下一个元素。

int hasStar(int n) {
    unordered_set<int>s;
    for(int i=0; i<n; ++i){
        s.insert(i);
    }
    while(s.size()>1){
        for(auto it1=s.begin(); it1!=s.end(); ++it1){
            for(auto it2=++s.begin(); it2!=s.end(); ++it2){
                if(know(*(it1), *(it2)){
                    s.erase(it1);
                    break;
                }
                else{
                    s.erase(it2);
                }
            }
        }
    }

    int flag=(*s.begin());
    for(int i=0; i<n; ++i){
        if(i==flag)    continue;
        if(!know(i, flag) || know(flag, i))
            return -1;
    }
    return flag;
}

方法2:用标记数组代替哈希表来写。

int hasStar(int n)
{
    vector<int> flag(n, 1);
    for (int i = 0; i < n; ++i){
        if (flag[i] == 0)    continue;
        for (int j = i + 1; j < n; ++j){
            if (know(i,j)){
                flag[i] = 0;
                break;
            }
            else{
                flag[j] = 0;
            }
        }
    }
 
        //最后一定会剩下一个元素,但是剩下的不一定是明星
    for (int i = 0; i < n; ++i){
        if (flag[i] == 1){
            for (int j = 0; j < n; ++j){
                if(j==i)    continue;
                if (know(i,j) || !know(j,i))
                    return -1;
            }
            return i;
        }
    }
}

方法3:将以上两种方法优化一下,其实我们不需要哈希表,也不需要flag标记数组。第一步的目的,只是想找出可能是明星的那个人,只需要扫一遍就可以了,不需要标记。

int hasStar(int n) {
    int i=0;
    for(int j=1; j<n; ++j){
        if(know(i,j)){
            i=j;
        }
    }
 
    //最后剩下i,但是i不一定是明星
    for(int j=0; j<n; ++j){
        if(j==i)    continue;
        if(know(i,j) || !know(j,i))
            return -1;
    }
    return i;
}

猜你喜欢

转载自blog.csdn.net/Scarlett_Guan/article/details/82146198
1.
今日推荐