牛客NC185 岛屿的最大面积【中等 并查集/DFS 提供Java,Go,PHP答案】

文章介绍了如何使用并查集数据结构,结合DFS方法,在Java、Go和PHP三种编程语言中解决二维数组中找到最大岛屿面积的问题。通过遍历数组,对相邻的1表示的格子进行合并,最后统计并查集中最大集合的大小即为最大岛屿面积。
摘要由CSDN通过智能技术生成

题目

在这里插入图片描述
在这里插入图片描述
题目链接:
https://www.nowcoder.com/practice/5568943d3a08403f932a5e54ec3ece71

思路

方法1:并查集,并查集通常用来求集合问题
方法2:DFS,  本答案利用并查集来解决

参考答案Java

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param grid int整型二维数组
     * @return int整型
     */
    public int maxAreaIsland (int[][] grid) {
        //并查集
        if (grid == null || grid.length == 0 || grid[0] == null) return 0;

        int n = grid.length;
        int m = grid[0].length;
        UF uf = new UF();
        int[] dirx = {-1, 1, 0, 0};
        int[] diry = {0, 0, -1, 1};


        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int idx = i * m + j;
                if (grid[i][j] == 1) {
                    uf.find(idx);

                    for (int k = 0; k < 4; k++) {
                        int nx = i + dirx[k];
                        int ny = j + diry[k];
                        int nidx = nx * m + ny;
                        if (nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] == 1) {
                            uf.union(idx, nidx);
                        }
                    }
                }

            }
        }

        //System.out.println(uf.size+" "+uf.sets);
        return uf.maxSize;
    }

    static class
        UF {//unionfind的标准写法之一,用map【另一种用数组】
        public Map<Integer, Integer> parents = new HashMap<>();
        public Map<Integer, Integer> size = new HashMap<>();
        public Map<Integer, Integer> help = new HashMap<>();
        public int sets;
        public int maxSize;  //本题特有的,存储最大的集合的个数

        public int find(int x) { //路径压缩
            if (!parents.containsKey(x)) {
                parents.put(x, x);
                size.put(x, 1);
                sets++;
            }

            int hi = 0;
            while (x != parents.get(x)) {
                help.put(hi++, x);
                x = parents.get(x);
            }

            for (hi--; hi >= 0; hi--) {
                parents.put(help.get(hi), x);
            }

            maxSize = Math.max(maxSize, size.get(x));
            return x;
        }

        public void union(int a, int b) {
            int f1 = find(a);
            int f2 = find(b);
            if (f1 != f2) {
                int s1 = size.get(f1);
                int s2 = size.get(f2);

                if (s1 >= s2) {
                    size.put(f1, s1 + s2);
                    parents.put(f2, f1);
                } else {
                    size.put(f2, s1 + s2);
                    parents.put(f1, f2);
                }
                maxSize = Math.max(maxSize, s1 + s2);
                sets--;
            }
        }
    }
}

参考答案Go

package main

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param grid int整型二维数组
 * @return int整型
 */
func maxAreaIsland(grid [][]int) int {
	//并查集
	if grid == nil || len(grid) == 0 || grid[0] == nil {
		return 0
	}

	uf := UF{map[int]int{}, map[int]int{}, map[int]int{}, 0, 0}
	n := len(grid)
	m := len(grid[0])
	dirx := []int{-1, 1, 0, 0}
	diry := []int{0, 0, -1, 1}

	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if grid[i][j] == 1 {
				idx := i*m + j
				uf.find(idx)
				for k := 0; k < 4; k++ {
					nx := i + dirx[k]
					ny := j + diry[k]
					nidx := nx*m + ny
					if nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] == 1 {
						uf.union(idx, nidx)

					}
				}
			}
		}
	}
	return uf.MaxSize
}

type UF struct {
	Parents map[int]int
	Size    map[int]int
	Help    map[int]int
	Sets    int
	MaxSize int
}

func (uf *UF) find(x int) int { //unionfind find,路径压缩
	_, keyexists := uf.Parents[x]
	if !keyexists {
		uf.Parents[x] = x
		uf.Size[x] = 1
		uf.Sets++
	}

	hi := 0
	for x != uf.Parents[x] {
		uf.Help[hi] = x
		x = uf.Parents[x]
	}

	for hi--; hi >= 0; hi-- {
		uf.Parents[uf.Help[hi]] = x
	}

	if uf.MaxSize < uf.Size[x] {
		uf.MaxSize = uf.Size[x]
	}
	return x
}

func (uf *UF) union(a, b int) { //union的union
	f1 := uf.find(a)
	f2 := uf.find(b)

	if f1 != f2 {
		sum := uf.Size[f1] + uf.Size[f2]
		if uf.Size[f1] >= uf.Size[f2] {
			uf.Size[f1] = sum
			uf.Parents[f2] = f1
		} else {
			uf.Size[f2] = sum
			uf.Parents[f1] = f2
		}
		if uf.MaxSize < sum {
			uf.MaxSize = sum
		}

		uf.Sets--
	}
}

参考答案PHP

<?php


/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param grid int整型二维数组 
 * @return int整型
 */
function maxAreaIsland( $grid )
{
   //并查集
    if ($grid == null || count($grid) == 0 || $grid[0] == null)
        return 0;

    $n = count($grid);
    $m = count($grid[0]);

    $uf = new UF();

    $dirx = [-1, 1, 0, 0];
    $diry = [0, 0, -1, 1];
    for ($i = 0; $i < $n; $i++) {
        for ($j = 0; $j < $m; $j++) {
            if ($grid[$i][$j] == 1) {
                $uf->find($grid[$i][$j]);
                $idx = $i * $m + $j;

                for ($k = 0; $k < 4; $k++) {
                    $nx = $i + $dirx[$k];
                    $ny = $j + $diry[$k];
                    $nidx = $nx * $m + $ny;

                    if ($nx >= 0 && $nx < $n && $ny >= 0 && $ny < $m && $grid[$nx][$ny] == 1) {
                        $uf->union($idx, $nidx);
                    }
                }
            }
        }
    }

    return $uf->maxSize;
}

class UF
{
    public $parents = [];
    public $size = [];
    public $help = [];
    public $sets = 0;
    public $maxSize = 0;

    public function find($x) //unionfind的find【核心】
    {
        if (empty($this->parents[$x])) {
            $this->parents[$x] = $x;
            $this->size[$x] = 1;
            $this->sets++;
        }

        $hi = 0;
        while (!empty($this->parents[$x]) && $x != $this->parents[$x]) {
            $this->help[$hi++] = $x;
            $x = $this->parents[$x];
        }

        for ($hi--; $hi >= 0; $hi--) {
            $this->parents[$this->help[$hi]] = $x;
        }
        if ($this->maxSize < $this->size[$x]) {
            $this->maxSize = $this->size[$x];
        }
        return $x;
    }

    public function union($a, $b) //union的union
    {
        $f1 = $this->find($a);
        $f2 = $this->find($b);

        if ($f1 != $f2) {
            $s1 = $this->size[$f1];
            $s2 = $this->size[$f2];

            if ($s1 >= $f2) {
                $this->size[$f1] = $s1 + $s2;
                $this->parents[$f2] = $f1;
            } else {
                $this->size[$f2] = $s1 + $s2;
                $this->parents[$f1] = $f2;
            }
            if ($this->maxSize < $s1 + $s2) {
                $this->maxSize = $s1 + $s2;
            }
            $this->sets--;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵长辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值