岛屿数量问题的另一种解法

使用矩阵表示的小岛问题的另一种解法

解题思路:递归的为遇到的非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;
    }
}

*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值