827. Making A Large Island

827. Making A Large Island


There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.

Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

Example 1:

Input: 
[[1,1,0],
 [1,1,0],
 [0,0,1]]
Output: 2
Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. 
The 2nd student himself is in a friend circle. So return 2.

Example 2:

Input: 
[[1,1,0],
 [1,1,1],
 [0,1,1]]
Output: 1
Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends, 

so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.

Note:

  1. N is in range [1,200].
  2. M[i][i] = 1 for all students.
  3. If M[i][j] = 1, then M[j][i] = 1.

方法1: dfs

xiaocong1990: https://blog.csdn.net/xiaocong1990/article/details/80627946

思路:

将这个问题拆分成几个子问题:

1.第一次dfs遍历,从所有的1入手,找到图中有多少个connected component,每一个component的面积是多少。这个信息我们用一个hashmap来记录,{id: area}。id 取0, 1 以外的数字,也就是从2开始,那么就可以代替visited这个矩阵,来辨认是否被遍历过。
2. 第二次遍历,从所有的0入手,检查它相邻的四个格子是否被标记了id,如果标记了,hash一下,并将这个cc所对应的面积加进来。记录一个全球最大值。

用到的数据结构:
unordered_map<int, int> concomp: 第一次遍历中记录{id: area}
unordered_set hash:在第二次遍历中记录每个0上下左右被相连的component id。

易错点

  1. 不要忘了加自己
  2. 上面第二个hash容易遗漏

Complexity

Time complexity: O(nm)
Space complexity: O(n
m)

class Solution {
public:
    int largestIsland(vector<vector<int>>& grid) {
        if (grid.empty() || grid[0].empty()) return 0;
        unordered_map<int, int> concomp;
        
        int id = 2;
        for (int i = 0; i < grid.size(); i++) {
            for (int j = 0; j < grid[0].size(); j ++) {
                if (grid[i][j] == 1) {
                     int area = dfs(grid, i, j, id, 1);
                     concomp[id] = area;
                     id++;
                }
            }
        }
        
        int result = 0;
        
        for (int i = 0; i < grid.size(); i++) {
            for (int j = 0; j < grid[0].size(); j ++) {
                if (grid[i][j] == 0) {
                    int area = 1;
                    unordered_set<int> hash = {(i > 0 ? grid[i - 1][j] : 0),
                                              (i < grid.size() - 1 ? grid[i + 1][j] : 0),
                                              (j > 0 ? grid[i][j - 1] : 0),
                                              (j < grid[0].size() - 1 ? grid[i][j + 1]: 0)};
                    
                    for (auto item: hash) {
                        area += concomp[item];
                    }
                    
                    result = max(result, area);
                }
                
            }
        }
        
        if (!result) return concomp.size() ? grid.size() * grid[0].size() : 0;
        return  result;
    }
    
    int dfs(vector<vector<int>> & grid, int i, int j, int id, int area) {
        if (i < 0 || i >= grid.size() || j < 0 || j >= grid[0].size() || grid[i][j] != 1) return 0;;
        
        grid[i][j] = id;
       
        return 1 
            + dfs(grid, i + 1, j, id, area) 
            + dfs(grid, i - 1, j, id, area)
            + dfs(grid, i, j - 1, id, area)
            + dfs(grid, i, j + 1, id, area);
    }
};

huahua: http://zxi.mytechroad.com/blog/graph/leetcode-827-making-a-large-island/
封装的更整洁的写法。

 // Author: Huahua
// Running time: 14 ms
class Solution {
public:
  int largestIsland(vector<vector<int>>& grid) {
    color_ = 1;
    g_ = &grid;
    m_ = grid.size();
    n_ = grid[0].size();
    unordered_map<int, int> areas; // color -> area
    int ans = 0;
    for (int i = 0; i < m_; ++i)
      for (int j = 0; j < n_; ++j)
        if (grid[i][j] == 1) {
          ++color_;
          areas[color_] = getArea(j, i);
          ans = max(ans, areas[color_]);
        }
    for (int i = 0; i < m_; ++i)
      for (int j = 0; j < n_; ++j)
        if (grid[i][j] == 0) {                    
          int area = 1;
          for (int color : set<int>{getColor(j, i - 1), getColor(j, i + 1),
                                    getColor(j - 1, i), getColor(j + 1, i)}) 
            area += areas[color];
          ans = max(ans, area);
        }
    return ans;
  }
private:
  int m_;
  int n_;
  int color_;
  vector<vector<int>>* g_; // does not own the object.
  
  int getColor(int x, int y) {
    return (x < 0 || x >= n_ || y < 0 || y >= m_) ? 0 : (*g_)[y][x];
  }
  
  // Return the area of a connected component, set all elements to color_.
  int getArea(int x, int y) {
    if (x < 0 || x >= n_ || y < 0 || y >= m_ || (*g_)[y][x] != 1) return 0;
    (*g_)[y][x] = color_;
    return 1 + getArea(x - 1, y) + getArea(x + 1, y) 
             + getArea(x, y - 1) + getArea(x, y + 1);
  }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: "making a os in 30 days.zip" 是一个名为「30天做一个操作系统.zip」的文件。它可能是一个包含制作操作系统教程或资源的压缩文件。 制作一个操作系统是一个复杂而庞大的任务,需要有深厚的计算机科学和编程知识。一个完整的操作系统由内核、系统调用、驱动程序、文件系统和用户界面等组件组成。为了实现这些组件,需要熟悉底层编程语言和硬件架构。 30天的时间对于初学者来说非常有限。要在如此短的时间内完成一个操作系统,你需要有很强的学习能力和编程经验。可能的情况是该文件可能包含一个有结构的教程,指导初学者按照一定的步骤来实现一个简单的操作系统。这样的教程通常会提供一些基本的框架和代码,以帮助学习者更好地理解操作系统的组成和原理。 然而,30天的时间无法涵盖操作系统开发的所有细节和复杂性。实际上,专业的操作系统开发往往需要数年的时间来完成。因此,这样一个限时任务更适合对操作系统开发有一定了解的人,而不是初学者。 总之,「30天做一个操作系统.zip」可能是一个提供操作系统开发教程或资源的文件。尽管如此,要在如此短的时间内制作一个完整的操作系统对于初学者来说是非常困难的任务,更适合有一定基础的开发者。 ### 回答2: "making a os in 30 days.zip" 是什么? "making a os in 30 days.zip" 是一个以压缩文件形式出现的项目或资源,该项目可能是一个教程、资源集合或文档,旨在教授关于在30天内制作操作系统的相关知识和技能。 制作一个操作系统是一项庞大而复杂的任务,需要深入了解计算机体系结构、编程语言、操作系统原理和底层硬件。这个压缩文件可能为想要学习或探索这些领域的人提供了一个系统的指导,帮助他们在短时间内建立起一个简单的操作系统。 在30天内制作操作系统需要具备坚实的编程基础和高度的自学能力。学习者可能会从构建基本的内核开始,然后逐渐添加功能和模块,直到最终得到一个完整的操作系统。 该压缩文件可能包含的内容可能是教程、代码示例、实践项目和其他参考资料。学习者可以按照其中的指导逐步完成每个步骤,通过实践来加深对操作系统概念和实现细节的理解。 要制作一个稳定且功能齐全的操作系统则需要更长的时间和更广泛的知识。然而,"making a os in 30 days.zip" 可以作为一个初学者入门的良好起点,为那些对操作系统开发感兴趣的人提供了机会,让他们在一个相对短的时间内了解操作系统的基本原理和实践应用。 ### 回答3: "making a os in 30 days.zip" 是一个名为“在30天内制作一个操作系统.zip”的文件。该文件可能是一个压缩文件,其中包含有关制作操作系统的相关信息和资源。 制作一个操作系统是一项复杂的任务,涉及到硬件、软件和系统设计的多个方面。在30天内完成一个完整的操作系统开发是一项非常困难的任务,需要对计算机体系结构和编程语言有深入的了解。 在这个.zip文件中可能包含了制作操作系统所需的代码、文档、示例程序、工具和其他资源。这些资源可能帮助用户了解操作系统的基本原理,理解操作系统的不同层次和模块,以及开始开发自己的操作系统。 一般来说,制作一个操作系统需要更多的时间和专业知识。在30天内制作一个操作系统只能是一个基础版本或者原型,可能存在一些限制和不成熟的功能。对于想要深入学习操作系统开发的人来说,这个.zip文件可能是一个很好的起点,提供了一些学习和实践的材料。 最后,制作一个操作系统是一个具有挑战性的任务。无论是从事这个项目还是研究操作系统开发,请准备好投入大量的时间和精力,并确保对计算机科学有一定的了解和经验,以便更好地理解和实践操作系统的设计和开发过程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值