三种方法:BFS 、 DFS 、并查集
<?php
class Solution {
private $visited = [];
private $parent = null;
private $provCnt = null;
/**
* DFS
* @param Integer[][] $isConnected
* @return Integer
*/
function findCircleNum($isConnected) {
$provCnt = count($isConnected);
if ($provCnt == 0) {
return 0;
}
$this->visited = array_fill(0, $provCnt, false);
$i = 0;
$cnt = 0;
while($i < $provCnt) {
if (!$this->visited[$i]) {
$this->dfs($isConnected, $i);
$cnt++;
}
$i++;
}
return $cnt;
}
function dfs(&$isConnected, $i) {
$this->visited[$i] = true;
foreach ($isConnected[$i] as $j => $_flgConn) {
if ($_flgConn == 1 && !$this->visited[$j]) {
$this->dfs($isConnected, $j);
}
}
}
/**
* BFS
* @param Integer[][] $isConnected
* @return Integer
*/
function findCircleNumv2($isConnected) {
$provCnt = count($isConnected);
if ($provCnt == 0) {
return 0;
}
$visited = array_fill(0, $provCnt, false);
$i = 0;
$cnt = 0;
while($i < $provCnt) {
if (!$visited[$i]) {
$queue = new SplQueue();
$queue->enqueue($i);
while (!$queue->isEmpty()) {
$provIdx = $queue->dequeue();
$visited[$provIdx] = true;
foreach ($isConnected[$provIdx] as $j => $flgConn) {
if ($flgConn == 1 && !$visited[$j]) {
$queue->enqueue($j);
}
}
}
$cnt++;
}
$i++;
}
return $cnt;
}
/**
* 并查集
* @param Integer[][] $isConnected
* @return Integer
*/
function findCircleNumv3($isConnected) {
$provCnt = count($isConnected);
if ($provCnt == 0) {
return 0;
}
$this->provCnt = $provCnt;
// 创建并查集
for ($i=0; $i<$provCnt; $i++) {
$this->parent[$i] = $i;
}
for ($i=0; $i<$provCnt; $i++) {
for ($j=$i+1; $j<$provCnt; $j++) {
if ($isConnected[$i][$j] == 1) {
$this->union($i, $j);
}
}
}
return $this->provCnt;
}
function union($i, $j) {
$i = $this->find($i);
$j = $this->find($j);
if ($i != $j) {
$this->provCnt--;
}
$this->parent[$j] = $i;
}
function find($idx) {
while ($this->parent[$idx] != $idx) {
$idx = $this->parent[$idx];
}
return $idx;
}
}