友人のLeetCode 547円

クラスN.の学生があります。それらのいくつかが友達である、いくつかはそうではありません。彼らの友情は推移でいます。あなたはAの友人Bを知っている場合は、B、Cは友人であるので、我々は、AはCの友人であると仮定することができます。友人のいわゆる円は、すべてのあなたの友人のセットです。

N * N行列Mを考えると、クラスの高校生との友情を表しています。もしM [i]の[J] = 1、そうでない場合は私は知らない、知られているi番目とj番目の生徒相互の友情を表しています。あなたは友人の既知の円の合計数は、すべての学生にエクスポートする必要があります。

例1:

入力します[[1,1,0]、
 [1,1,0]、
 [0,0,1]] 
出力:2 
説明:既知の学生と学生0 1共通の友人が、彼らは友人のサークルです。
友人のサークルの最初の2人の学生自身。2が返されます。

例2:

入力[[1,1,0]、
 [1,1,1]、
 [0,1,1]] 
出力:1つの
説明:知ら学生学生0と1の共通の友人、学生と学生2相互友人、学生と学生0 2も友人、友人、リターン1の円の中にそれらのように3になるように。

注意:

  1. 【1200】範囲内でN。
  2. すべての学生、M [i]は[I] = 1の場合。
  3. M [i]は[J] = 1の場合、M [j]は[I] = 1です。

 

分析:この質問は、マトリックスとして、質問の明確な意味を適用する必要があるの各値を表す行列のn * n個の位置は、友人としてではありません。

1は、実際には、この質問には、各値の要素の横にある下までについてですと検索時間に島の最大数を求め、その質問に行うための島々の最大数を追跡することができますが、同じ問題が同じ水平と垂直を検索することができます行のすべての値、検索のその後深さ(または幅の広い検索で)

図2は、互いに素な集合である溶液があります

1、深さ優先探索

    クラスのソリューション{
         int型のlen;
        公共 INT findCircleNum(INT [] [] M){ 
            LEN = m.length。
            int型 ANS = 0 ;
            以下のためにINT I 0 =; I <LEN; I ++ ){
                 ためINT J = 0; J <LEN; J ++ ){
                     場合(M [I] [J] == 1 ){ 
                        ANS ++ 
                        クリア(M、I、J)。
                    } 
                } 
            }
            戻り値は、ANS; 
        } 

        公共 ボイドクリア(INT [] [] M、整数 qは、整数P)
        { 
            場合(M [Q] [P] == 0 ){
                 リターン
            } 
            M [Q] [P] = 0 ;
            以下のためにINT I = 0; I <LEN; I ++ ){ 
                クリア(M、I、P)。
            } 
            ためINT iは= 0; I <LEN; I ++ ){ 
                クリア(M、Q、I)。
            } 
        } 
    }

 

2、幅優先探索

パブリック クラス場所{
     int型のX;
    int型のy; 
    位置(int型 M、INT N){ 
        X = M。
        Y = N。
    } 
} 

クラスソリューション{
     INT LEN。
    キュー <場所>キュー= 新しい LinkedListの<場所> ();
    公共 INT findCircleNum(INT [] [] M){ 
        LEN = m.length。
        int型 ANS = 0 ;
        以下のためのint型I = 0; 私は<lenは、I ++ ){
             ためINT J = 0; J <LEN; J ++ ){
                 場合(M [I] [J]!= 0 ){ 
                    ANS ++ 
                    queue.add(新しい場所(I、J));
                    一方、(!queue.size()= 0 ){ 
                        位置L = queue.remove()。
                        もし(!M [lx]と[LY] = 0 ){ 
                            M [lx]と[LY] = 0 ;
                            int型のk = 0; K <LEN、K ++){ 
                                queue.add(新しい場所(LX、K))。
                                queue.add(新しい場所(K、LY)); 
                            } 
                        } 
                    } 
                } 
            } 
        } 
        戻りANS。
    } 
}

 

 

3、互いに素セット

    クラスソリューション{
         INT [] ARR。
        INT []数えます。
        int型 allgroup = 0 ;
        公共 INT findCircleNum(INT [] [] M){
             int型のlen = m.length。
            もし(LEN == 0 ){
                 戻り 0 
            } 
            ARR = 新しい INT [LEN]。
            カウント数 = 新しい int型[LEN]。
            allgroup = LEN。
            以下のためのint型I = 0; 私は<lenは、I ++ ){ 
                [i]はARR = iは、
                カウント[I] = 1 ; 
            } 
            ためINT iは= 0; I <LEN; I ++ ){
                 ためINT J = 0; J <LEN; J ++ ){
                     場合(M [I] [J] == 0 ){
                         続けます
                    } 
                    INT roota = 見つける(I)。
                    int型 rootb = (j)を見つけます。
                    もし(roota == {rootb)
                        続け; 
                    } 
                    allgroup - もし(カウント[roota]> カウント[rootb]){ 
                        ARR [rootb] = roota。
                        カウント[roota] + = カウント[rootb]。
                    } { 
                        ARR [roota] = rootb。
                        カウント[rootb] + = カウント[roota]。
                    } 
                } 
            } 
            戻りallgroup。
        } 
        公共 のint検索(int型A){
             一方(ARR [A] =!)A = ARR [A]。
            返します
        } 
    }

 

おすすめ

転載: www.cnblogs.com/tobemaster/p/12408552.html