使用矩阵表示的小岛问题的另一种解法
解题思路:递归的为遇到的非0涂色
<?php
$strIsland = <<<STR
1 0 0 0 1 1 0 0
1 1 0 1 0 0 1 0
1 1 1 1 0 0 1 1
0 0 0 1 0 0 1 0
STR;
$graph = [];
$lines = explode(PHP_EOL, $strIsland);
$row = 0;
foreach( $lines as $line )
{
$items = explode( ' ', $line );
$graph[$row] = [];
foreach( $items as $item )
{
$graph[$row][] = ['val' => $item, 'v' => false];//v for visited
}
$row++;
}
print_graph($graph);
$color = 1;
foreach( $graph as $row_index => $rows )
{
foreach( $rows as $column_index => $item )
{
$island = get_direct_conn($graph, $row_index, $column_index );
$color = paint($graph, $island, $color);
}
}
echo PHP_EOL;
echo PHP_EOL;
print_graph($graph);
if( $color > 1 )
{
echo 'island count: ', $color - 1, PHP_EOL;
}
function paint( &$graph, $island, $color = 1 )
{
if( empty( $island ))
{
return $color;
}
$color++;
foreach( $island as $row_index => $elem )
{
$graph[$elem['r']][$elem['c']]['val'] = $color;
}
return $color;
}
function get_direct_conn(&$graph, $row_index, $column_index)
{
$island = [];
$center = $graph[$row_index][$column_index];
if( 1 != $center['val'] )
{
return $island;
}
if( !$center['v'] )
{
$island[] = [ 'r' => $row_index, 'c' => $column_index];
$graph[$row_index][$column_index]['v'] = true;
}
//left
if( isset($graph[$row_index][$column_index - 1]) )
{
$elem = $graph[$row_index][$column_index - 1];
if( $elem['val'] == 1 && !$elem['v'] )
{
$island[] = ['r' => $row_index, 'c' => $column_index - 1];
$graph[$row_index][$column_index - 1]['v'] = true;
$island = array_merge($island, get_direct_conn($graph, $row_index, $column_index - 1));
}
}
//right
if( isset($graph[$row_index][$column_index + 1]) )
{
$elem = $graph[$row_index][$column_index + 1];
if( $elem['val'] == 1 && !$elem['v'])
{
$island[] = [ 'r' => $row_index, 'c' => $column_index + 1];
$graph[$row_index][$column_index + 1]['v'] = true;
$island = array_merge($island, get_direct_conn($graph, $row_index, $column_index + 1));
}
}
//top
if( isset($graph[$row_index - 1][$column_index]) )
{
$elem = $graph[$row_index - 1][$column_index];
if( $elem['val'] == 1 && !$elem['v'])
{
$island[] = ['r' => $row_index - 1, 'c' => $column_index];
$graph[$row_index - 1][$column_index]['v'] = true;
$island = array_merge($island, get_direct_conn($graph, $row_index - 1, $column_index));
}
}
//bottom
if( isset($graph[$row_index + 1][$column_index]) )
{
$elem = $graph[$row_index + 1][$column_index];
if( $elem['val'] == 1 && !$elem['v'] )
{
$island[] = ['r' => $row_index + 1, 'c' => $column_index];
$graph[$row_index + 1][$column_index]['v'] = true;
$island = array_merge($island, get_direct_conn($graph, $row_index + 1, $column_index));
}
}
return $island;
}
function print_graph($arr)
{
foreach( $arr as $line )
{
foreach( $line as $item )
{
echo $item['val'], ' ';
}
echo PHP_EOL;
}
}
/*
<?php
$strIsland = <<<STR
1 0 0 0 1 1 0 0
1 1 0 1 0 0 1 0
1 1 1 1 0 0 1 1
0 0 0 1 0 0 1 0
STR;
$graph = [];
$lines = explode(PHP_EOL, $strIsland);
$row = 0;
foreach( $lines as $line )
{
$items = explode( ' ', $line );
$graph[$row] = [];
foreach( $items as $item )
{
$graph[$row][] = ['val' => $item, 'v' => false];//v for visited
}
$row++;
}
print_graph($graph);
$color = 1;
foreach( $graph as $row_index => $rows )
{
foreach( $rows as $column_index => $item )
{
$island = get_direct_conn($graph, $row_index, $column_index );
$color = paint($graph, $island, $color);
}
}
echo PHP_EOL;
echo PHP_EOL;
print_graph($graph);
if( $color > 1 )
{
echo 'island count: ', $color - 1, PHP_EOL;
}
function paint( &$graph, $island, $color = 1 )
{
if( empty( $island ))
{
return $color;
}
$color++;
foreach( $island as $row_index => $elem )
{
$graph[$elem['r']][$elem['c']]['val'] = $color;
}
return $color;
}
function has_neighber(&$graph, $r, $c )
{
if( isset($graph[$r][$c]) )
{
$elem = $graph[$r][$c];
if( $elem['val'] == 1 && !$elem['v'] )
{
$graph[$r][$c]['v'] = true;
return true;
}
}
return false;
}
function get_direct_conn(&$graph, $row_index, $column_index)
{
$island = [];
$center = $graph[$row_index][$column_index];
if( 1 != $center['val'] )
{
return $island;
}
if( !$center['v'] )
{
$island[] = [ 'r' => $row_index, 'c' => $column_index];
$graph[$row_index][$column_index]['v'] = true;
}
//left
$r = $row_index;
$c = $column_index - 1;
if( has_neighber($graph, $r, $c ))
{
$island[] = ['r' => $r, 'c' => $c];
$island = array_merge($island, get_direct_conn($graph, $r, $c));
}
//right
$r = $row_index;
$c = $column_index + 1;
if( has_neighber($graph, $r, $c ))
{
$island[] = ['r' => $r, 'c' => $c];
$island = array_merge($island, get_direct_conn($graph, $r, $c));
}
//top
$r = $row_index - 1;
$c = $column_index;
if( has_neighber($graph, $r, $c ))
{
$island[] = ['r' => $r, 'c' => $c];
$island = array_merge($island, get_direct_conn($graph, $r, $c));
}
//bottom
$r = $row_index + 1;
$c = $column_index;
if( has_neighber($graph, $r, $c ))
{
$island[] = ['r' => $r, 'c' => $c];
$island = array_merge($island, get_direct_conn($graph, $r, $c));
}
return $island;
}
function print_graph($arr)
{
foreach( $arr as $line )
{
foreach( $line as $item )
{
echo $item['val'], ' ';
}
echo PHP_EOL;
}
}
*/