找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4445

积分

0

好友

586

主题
发表于 3 小时前 | 查看: 3| 回复: 0

最近在网上流传的一张“公司员工工作状态分析报告”截图,让不少打工人心头一紧。这张图通过网络分析,清晰地展示了全公司的平均工作占比、准时上线率,甚至细化到哪些IP地址的设备在工作期间频繁访问小红书、抖音、BOSS直聘等网站。

网友们纷纷评论:“这以后谁还敢连公司WiFi”。虽然我们都知道公司网络管理员有能力看到流量去向,但如此直观的数据呈现在眼前,还是难免让人背后一凉。笔者自己也警醒了一下,毕竟谁还没在工作间隙“摸过鱼”呢?不过转念一想,仅凭IP地址,公司大概率无法直接对应到具体个人(除非做了MAC地址绑定等额外配置),但这无疑是一个强烈的信号:在公司的网络环境下,你的“数字足迹”几乎是透明的

公司网络分析报告截图

评论区更是大型“人间真实”现场,充满了程序员的调侃与自省:

脉脉评论区关于公司WiFi的讨论截图

关于公司网络行为的评论截图

有网友指出,公司网络可以通过安装证书等方式进行深度包检测,隐私基本无从谈起;也有网友表示,这就是常规的“行为管理”;更有甚者,听说有公司开始以连接WiFi的时间来统计工时了。无论技术细节如何,这都提醒我们,对于网络安全和隐私保护需要多一份警惕。

话题从略显沉重的职场监控跳转一下,作为一名开发者,保持对数据结构和算法的敏锐同样重要。下面就来一起看看今天这道来自LeetCode的算法题——第1905题:统计子岛屿

问题描述

给你两个 m x n 的二进制矩阵 grid1grid2,它们只包含 0 (表示水域)和 1 (表示陆地)。一个岛屿 是由四个方向 (水平或者竖直)上相邻的 1 组成的区域。任何矩阵以外的区域都视为水域。

如果 grid2 中的一个岛屿,被 grid1 的一个岛屿完全包含,也就是说 grid2 中该岛屿的每一个格子都被 grid1 中同一个岛屿完全包含,那么我们称 grid2 中的这个岛屿为 子岛屿

请你返回 grid2子岛屿 的数目。

示例 1:

LeetCode 1905题示例图1

输入:grid1 = 1,1,1,0,0],[0,1,1,1,1],[0,0,0,0,0],[1,0,0,0,0],[1,1,0,1,1, grid2 = 1,1,1,0,0],[0,0,1,1,1],[0,1,0,0,0],[1,0,1,1,0],[0,1,0,1,0
输出:3
解释:如上图所示,左边为 grid1 ,右边为 grid2 。grid2 中标红的 1 区域是子岛屿,总共有 3 个子岛屿。

示例 2:

LeetCode 1905题示例图2

输入:grid1 = 1,0,1,0,1],[1,1,1,1,1],[0,0,0,0,0],[1,1,1,1,1],[1,0,1,0,1, grid2 = 0,0,0,0,0],[1,1,1,1,1],[0,1,0,1,0],[0,1,0,1,0],[1,0,0,0,1
输出:2
解释:如上图所示,左边为 grid1 ,右边为 grid2 。grid2 中标红的 1 区域是子岛屿,总共有 2 个子岛屿。

提示:

  • m == grid1.length == grid2.length
  • n == grid1[i].length == grid2[i].length
  • 1 <= m, n <= 500
  • grid1[i][j]grid2[i][j] 都要么是 0 要么是 1

解题思路

这道题要求我们计算 grid2 中有多少个岛屿是 grid1 中某个岛屿的子岛屿。关键在于理解“完全包含”的定义:grid2 中一个岛屿的所有陆地单元格,在 grid1 的相同位置上,必须都属于同一个岛屿。

一个直观的思路是两步走:

  1. grid1 中的岛屿编号:遍历 grid1,使用深度优先搜索(DFS)或广度优先搜索(BFS)找到所有连通区域(岛屿),并为每个岛屿赋予一个唯一的编号(例如从2开始,避免与原始的0、1冲突)。
  2. grid2 中寻找子岛屿:遍历 grid2,当遇到一块陆地(1)时,检查其在 grid1 中相同位置的值。
    • 如果 grid1 对应位置是水(0),那么 grid2 中以该位置为起点的整个岛屿都不可能是子岛屿。
    • 如果 grid1 对应位置是一个岛屿(编号>=2),则以此位置为起点,对 grid2 进行DFS/BFS,探索整个岛屿。在探索过程中,需要检查 grid2 岛屿的每一个陆地单元格,其在 grid1 中的编号是否都与起点位置在 grid1 中的编号完全相同
    • 如果全部相同,则找到一个子岛屿;如果在探索过程中发现任何一处编号不同,则当前 grid2 的岛屿不是子岛屿。

代码实现

以下是使用DFS的Java和C++实现。

Java 版本:

private boolean isChild = true;// 是否是子岛屿

public int countSubIslands(int[][] grid1, int[][] grid2) {
    int m = grid1.length, n = grid1[0].length;
    int index = 2;// 给岛屿编号,相连的陆地是一个岛屿,他们的编号相同。
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (grid1[i][j] == 1)
                dfs1(grid1, i, j, index++);
        }
    }
    int ans = 0;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            // 找到grid2的所有岛屿,且每个岛屿中每个位置都与岛屿1中该位置的岛屿编号相同,才算一个子岛屿
            if (grid2[i][j] == 1 && grid1[i][j] >= 2) {
                isChild = true;
                dfs2(grid2, i, j, grid1[i][j], grid1);
                if (isChild)
                    ans++;
            }
        }
    }
    return ans;
}

// 遍历矩阵1
private void dfs1(int[][] grid1, int i, int j, int index) {
    if (i < 0 || i >= grid1.length || j < 0 || j >= grid1[0].length || grid1[i][j] != 1)
        return;
    grid1[i][j] = index;// 挨着的陆地属于同一个岛屿
    dfs1(grid1, i - 1, j, index);// 上
    dfs1(grid1, i + 1, j, index);// 下
    dfs1(grid1, i, j - 1, index);// 左
    dfs1(grid1, i, j + 1, index);// 右
}

// 遍历矩阵2
private void dfs2(int[][] grid2, int i, int j, int index, int[][] grid1) {
    if (i < 0 || i >= grid2.length || j < 0 || j >= grid2[0].length || grid2[i][j] != 1)
        return;
    grid2[i][j] = -1;
    if (grid1[i][j] != index)
        isChild = false;// 不是子岛屿
    dfs2(grid2, i - 1, j, index, grid1);// 上
    dfs2(grid2, i + 1, j, index, grid1);// 下
    dfs2(grid2, i, j - 1, index, grid1);// 左
    dfs2(grid2, i, j + 1, index, grid1);// 右
}

C++ 版本:

public:
    int countSubIslands(vector<vector<int>>& grid1, vector<vector<int>>& grid2) {
        int m = grid1.size();
        int n = grid1[0].size();
        int index = 2; // 给岛屿编号,相连的陆地是一个岛屿,他们的编号相同。
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid1[i][j] == 1)
                    dfs1(grid1, i, j, index++);
            }
        }

        int ans = 0;
        // 第二步:遍历 grid2,统计子岛屿数量
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                // 找到grid2的所有岛屿,且每个岛屿中每个位置都与岛屿1中该位置的岛屿编号相同,才算一个子岛屿
                if (grid2[i][j] == 1 && grid1[i][j] >= 2) {
                    isChild = true; // 重置标记
                    dfs2(grid2, i, j, grid1[i][j], grid1);
                    if (isChild)  // 如果是子岛屿,计数+1
                        ans++;
                }
            }
        }
        return ans;
    }

private:
    bool isChild = true;// 是否是子岛屿
    // 遍历矩阵1,给岛屿编号
    void dfs1(vector<vector<int>>& grid1, int i, int j, int index) {
        // 边界和合法性检查
        if (i < 0 || i >= grid1.size() || j < 0 || j >= grid1[0].size() || grid1[i][j] != 1)
            return;
        grid1[i][j] = index;// 挨着的陆地属于同一个岛屿// 挨着的陆地属于同一个岛屿
        // 上下左右递归遍历
        dfs1(grid1, i - 1, j, index); // 上
        dfs1(grid1, i + 1, j, index); // 下
        dfs1(grid1, i, j - 1, index); // 左
        dfs1(grid1, i, j + 1, index); // 右
    }

    // 遍历矩阵2,判断是否为子岛屿
    void dfs2(vector<vector<int>>& grid2, int i, int j, int index, vector<vector<int>>& grid1) {
        // 边界和合法性检查
        if (i < 0 || i >= grid2.size() || j < 0 || j >= grid2[0].size() || grid2[i][j] != 1)
            return;
        // 标记 grid2 ,避免重复遍历
        grid2[i][j] = -1;
        // 如果 grid1 对应位置的编号不一致,说明不是子岛屿
        if (grid1[i][j] != index)
            isChild = false;
        // 上下左右递归遍历
        dfs2(grid2, i - 1, j, index, grid1); // 上
        dfs2(grid2, i + 1, j, index, grid1); // 下
        dfs2(grid2, i, j - 1, index, grid1); // 左
        dfs2(grid2, i, j + 1, index, grid1); // 右
    }
};

总结

从警惕公司WiFi下的“数字裸奔”,到攻克一道关于岛屿包含关系的算法题,看似跳跃,实则都关乎“边界”与“规则”。前者是职场与隐私的边界,后者是算法中严谨的逻辑规则。作为开发者,我们既需要了解现实世界中的技术应用边界,保护自身权益,也需要持续锤炼解决复杂逻辑问题的能力。对这道题或者职场技术话题有更多想法?欢迎在云栈社区交流讨论。




上一篇:Redis跳表源码深度解析:数据结构与算法如何支撑ZSet的高性能排序
下一篇:NVIDIA Vera CPU正式发布:88核Arm架构,专为智能体AI优化
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-20 07:04 , Processed in 0.494660 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表