827. Making A Large Island

package LeetCode_827

import java.util.*
import kotlin.collections.HashMap

/**
 * 827. Making A Large Island
 * https://leetcode.com/problems/making-a-large-island/
 *
 * In a 2D grid of 0s and 1s, we change at most one 0 to a 1.
After, what is the size of the largest island? (An island is a 4-directionally connected group of 1s).

Example 1:
Input: [[1, 0], [0, 1]]
Output: 3
Explanation: Change one 0 to 1 and connect two 1s, then we get an island with area = 3.
 * */
class Solution {
    /*
    * Solution: DFS,BFS,HashMap,HashSet, Time complexity:O(mn), Space complexity:O(mn);
    * 1. DFS to find out the large island and save every island'id in map and mapping size of island,
    * 2. BFS to determine what's max island size is when we change zeros to ones, and we use HashSet to help us sum up the
    * island with same unique ID,
    * */
    fun largestIsland(grid: Array<IntArray>): Int {
        if (grid == null || grid.isEmpty()) {
            return 0
        }
        var max = 0
        //because grid has contains 0,1
        var isLandId = 2
        //key: islandId, value:size the island
        val map = HashMap<Int, Int>()
        val m = grid.size
        val n = grid[0].size
        for (i in 0 until m) {
            for (j in 0 until n) {
                //when we meet island, start to find the island size
                if (grid[i][j] == 1) {
                    val size = islandSize(grid, i, j, isLandId)
                    //keep update the max area
                    max = Math.max(max,size)
                    //mapping the islandId and its area size
                    map.put(isLandId, size)
                    //increase the islandId to ensure have unique id
                    isLandId++
                }
            }
        }
        //start bfs
        val queue = LinkedList<Pair<Int, Int>>()
        //4 directions
        val directions = intArrayOf(0, 1, 0, -1, 0)
        //queue to save all non island
        for (i in 0 until m) {
            for (j in 0 until n) {
                if (grid[i][j] == 0) {
                    queue.offer(Pair(i, j))
                }
            }
        }
        while (queue.isNotEmpty()) {
            val cur = queue.pop()
            val set = HashSet<Int>()
            //temp init is 1, because this can be change into 1
            var temp = 1
            for (d in 0 until 4) {
                val x = cur.first + directions[d]
                val y = cur.second + directions[d + 1]
                if (x < 0 || y < 0 || x >= m || y >= n || grid[x][y]==0) {
                    continue
                }
                val value = grid[x][y]
                if (!set.contains(value)) {
                    set.add(value)
                    temp += map.get(value) ?: 0
                }
            }
            max = Math.max(max, temp)
        }
        return max
    }

    private fun islandSize(grid: Array<IntArray>, i: Int, j: Int, islandId: Int): Int {
        if (i < 0 || j < 0 || i >= grid.size || j >= grid[0].size || grid[i][j] != 1) {
            return 0
        }
        //set this position to current islandId
        grid[i][j] = islandId
        //calculate 4 directions
        val left = islandSize(grid, i-1, j, islandId)
        val right = islandSize(grid, i+1, j, islandId)
        val top = islandSize(grid, i, j-1, islandId)
        val bottom = islandSize(grid, i, j+1, islandId)
        return left + right + top + bottom + 1
    }
}
原文地址:https://www.cnblogs.com/johnnyzhao/p/13999919.html