[力扣题解] 827. 最大人工岛

题目:827. 最大人工岛 困难

思路

(1) 用深度优先搜索遍历每一个岛,统计它们的面积;
(2) 遍历每一块海洋地块,往周边探索,如果探索到陆地,标记上已探索,加上该地块所在岛屿面积,统计累计面积的最大值;

用到的数据结构有:
unordered_map, unordered_set
新手别混淆了;

代码

class Solution 
{
    private:
        int dir[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
        int count_S = 0; // 统计每个岛屿的面积
        bool isAllLand = true;
        int result = 0;
        void dfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y, int mark)
        {
            int i, j;
            int m = grid.size(), n = grid[0].size();
            int next_x, next_y;

            for (i = 0; i < 4; i++)
            {
                next_x = x + dir[i][0];
                next_y = y + dir[i][1];

                if (next_x < 0 || next_x >= m || next_y < 0 || next_y >= n)
                {
                    continue;
                }
                if (grid[next_x][next_y] == 0)
                {
                    isAllLand = false;
                }
                if (!visited[next_x][next_y] && grid[next_x][next_y] == 1)
                {
                    count_S++;
                    visited[next_x][next_y] = true;
                    grid[next_x][next_y] = mark;
                    dfs(grid, visited, next_x, next_y, mark);
                }
            }
        }

    public:
        int largestIsland(vector<vector<int>>& grid)
        {
            int i, j, k;
            int m = grid.size(), n = grid[0].size();
            int mark = 1; // 因为地图上已经有了`0,1`
            unordered_map<int, int> islandNum; // 编号 -> 面积
            vector<vector<bool>> visited(m, vector<bool>(n, 0));
               
            unordered_set<int> visited_island; // 标记访问过的岛屿
            int count_S_all = 0;              // 记录连接之后的岛屿面积 
            int near_i, near_j;

            for (i = 0; i < m; i++)
            {
                for (j = 0; j < n; j++)
                {
                    if (grid[i][j] == 0)
                    {
                        isAllLand = false;
                    }
                    if (!visited[i][j] && grid[i][j] == 1)
                    {
                        count_S = 1;
                        visited[i][j] = true;
                        mark++;                         // 这样从 2 开始
                        grid[i][j] = mark;
                        dfs(grid, visited, i, j, mark);
                        islandNum[mark] = count_S;
                    }
                }
            }
            
            // 如果全是陆地
            if (isAllLand)
            {
                return m * n;
            }
            
            // 看不懂,开抄
            for (i = 0; i < m; i++)
            {
                for (j = 0; j < n; j++)
                {
                    if (grid[i][j] == 0)
                    {
                        // 假设把[i, j]填成陆地
                        count_S_all = 1;
                        visited_island.clear();
                        for (k = 0; k < 4; k++)
                        {
                            near_i = i + dir[k][0];
                            near_j = j + dir[k][1];
                            if (near_i < 0 || near_i >= m || near_j < 0 || near_j >= n)
                            {
                                continue;
                            }
                            if (grid[near_i][near_j] == 0)
                            {
                                continue;
                            }
                            if (visited_island.count(grid[near_i][near_j]))
                            {
                                continue;
                            }
                            count_S_all += islandNum[grid[near_i][near_j]]; // 把这个[near_i, near_j]所在的岛的面积加起来
                            visited_island.insert(grid[near_i][near_j]);
                        }
                        result = max(result, count_S_all);
                    }
                }
            }

            // --------------------------------------------------------------------
            return result;
        }
};

本地调试用

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
using namespace std;

class Solution 
{
    private:
        int dir[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
        int count_S = 0; // 统计每个岛屿的面积
        bool isAllLand = true;
        int result = 0;
        void dfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y, int mark)
        {
            int i, j;
            int m = grid.size(), n = grid[0].size();
            int next_x, next_y;

            for (i = 0; i < 4; i++)
            {
                next_x = x + dir[i][0];
                next_y = y + dir[i][1];

                if (next_x < 0 || next_x >= m || next_y < 0 || next_y >= n)
                {
                    continue;
                }
                if (grid[next_x][next_y] == 0)
                {
                    isAllLand = false;
                }
                if (!visited[next_x][next_y] && grid[next_x][next_y] == 1)
                {
                    count_S++;
                    visited[next_x][next_y] = true;
                    grid[next_x][next_y] = mark;
                    dfs(grid, visited, next_x, next_y, mark);
                }
            }
        }

    public:
        int largestIsland(vector<vector<int>>& grid)
        {
            int i, j, k;
            int m = grid.size(), n = grid[0].size();
            int mark = 1; // 因为地图上已经有了`0,1`
            unordered_map<int, int> islandNum; // 编号 -> 面积
            vector<vector<bool>> visited(m, vector<bool>(n, 0));
               
            unordered_set<int> visited_island; // 标记访问过的岛屿
            int count_S_all = 0;              // 记录连接之后的岛屿面积 
            int near_i, near_j;

            for (i = 0; i < m; i++)
            {
                for (j = 0; j < n; j++)
                {
                    if (grid[i][j] == 0)
                    {
                        isAllLand = false;
                    }
                    if (!visited[i][j] && grid[i][j] == 1)
                    {
                        count_S = 1;
                        visited[i][j] = true;
                        mark++;                         // 这样从 2 开始
                        grid[i][j] = mark;
                        dfs(grid, visited, i, j, mark);
                        islandNum[mark] = count_S;
                    }
                }
            }
            
            // 如果全是陆地
            if (isAllLand)
            {
                return m * n;
            }
            /**/
            cout << "grid : " << endl;
            for (i = 0; i < m; i++)
            {
                for (j = 0; j < n; j++)
                {
                    cout << grid[i][j] << ", ";
                }
                cout << endl;
            }

            for (const auto& pair : islandNum)
            {
                cout << pair.first << " - " << pair.second << ", ";
            }
            // ------------------------------------------------------
            cout << endl;
            

            // 看不懂,开抄
            for (i = 0; i < m; i++)
            {
                for (j = 0; j < n; j++)
                {
                    if (grid[i][j] == 0)
                    {
                        // 假设把[i, j]填成陆地
                        count_S_all = 1;
                        visited_island.clear();
                        for (k = 0; k < 4; k++)
                        {
                            near_i = i + dir[k][0];
                            near_j = j + dir[k][1];
                            if (near_i < 0 || near_i >= m || near_j < 0 || near_j >= n)
                            {
                                continue;
                            }
                            if (grid[near_i][near_j] == 0)
                            {
                                continue;
                            }
                            if (visited_island.count(grid[near_i][near_j]))
                            {
                                continue;
                            }
                            count_S_all += islandNum[grid[near_i][near_j]]; // 把这个[near_i, near_j]所在的岛的面积加起来
                            visited_island.insert(grid[near_i][near_j]);
                        }
                        result = max(result, count_S_all);
                    }
                }
            }

            // --------------------------------------------------------------------
            return result;
        }
};


int main()
{
    /*
    vector<vector<int>> input = { {1, 1, 0, 1} ,
                                  {1, 0, 0, 1} ,
                                  {0, 1, 1, 0} ,
                                  {1, 0, 1, 1} };*/
    vector<vector<int>> input = { {1, 0},
                                  {0, 1} };
    Solution solution;
    cout << solution.largestIsland(input) << endl;
    
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值