【LeetCode】员工的重要性 | 图像渲染 | 岛屿问题

news2025/1/16 0:56:52

​🌠 作者:@阿亮joy.
🎆专栏:《阿亮爱刷题》
🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根
在这里插入图片描述


目录

    • 👉员工的重要性👈
    • 👉图像渲染👈
    • 👉被环绕的区域👈
    • 👉岛屿的周长👈
    • 👉岛屿的数量👈
    • 👉岛屿的最大面积👈
    • 👉总结👈

👉员工的重要性👈

给定一个保存员工信息的数据结构,它包含了员工 唯一的 id ,重要度 和 直系下属的 id 。

比如,员工 1 是员工 2 的领导,员工 2 是员工 3 的领导。他们相应的重要度为 15 , 10 , 5 。那么员工 1 的数据结构是 [1, 15, [2]] ,员工 2的数据结构是 [2, 10, [3]] ,员工 3 的数据结构是 [3, 5, []] 。注意虽然员工 3 也是员工 1 的一个下属,但是由于并不是直系下属,因此没有体现在员工 1 的数据结构中。

现在输入一个公司的所有员工信息,以及单个员工 id ,返回这个员工和他所有下属的重要度之和。


在这里插入图片描述

思路:员工和领导的关心可以抽象成一块多叉树,想要求出一个员工和他所有下属的重要度之和,可以将该员工看做根节点,然后递归去求其所有子树的重要性之和,就能够得到总的重要性了。

在这里插入图片描述

/*
// Definition for Employee.
class Employee {
public:
    int id;
    int importance;
    vector<int> subordinates;
};
*/

class Solution 
{
private:
    int DFS(unordered_map<int, Employee*>& info, int id)
    {
        int ret = info[id]->importance; // 自己的重要性
        for(auto& id : info[id]->subordinates)
        {
            // 递归去求所有下属的重要性
            ret += DFS(info, id);  
        }
        return ret;
    }
public:
    int getImportance(vector<Employee*> employees, int id) 
    {
        // 使用哈希表来建立id和节点指针的关系
        // 有了节点指针就能够找到其所有直系下属的id
        unordered_map<int, Employee*> info;
        for(auto& e : employees)
        {
            info[e->id] = e;
        }
        return DFS(info, id);
    }
};

在这里插入图片描述

👉图像渲染👈

这里是引用

思路:本道题的意思是给定一个起点 (sr, sc) 和 新颜色 newColor,记该起点的颜色为 oldColor,将起点和其上向左右为 oldColor 的点的颜色都改为 newColor。借助递归就能够修改上下左右的颜色了,重要的是判断上下左右是否越界。

class Solution 
{
private:
    // 向上下左右移动一格
    int nextPosition[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    void DFS(vector<vector<int>>& image, vector<vector<bool>>& mark, int X, int Y, int oldColor, int newColor)
    {
        // 修改当前格子的颜色,并标记为true
        image[X][Y] = newColor;
        mark[X][Y] = true;
        for(int i = 0; i < 4; ++i)
        {
            int newX = X + nextPosition[i][0];
            int newY = Y + nextPosition[i][1];
            // 判断是否越界
            if(newX >= image.size() || newX < 0
            || newY >= image[0].size() || newY < 0)
                continue;
            
            // 如果当前格子颜色为oldColor且没有被标记成true
            // 就递归去修改颜色
            if(image[newX][newY] == oldColor && mark[newX][newY] == false)
                DFS(image, mark, newX, newY, oldColor, newColor);
        }
    }

public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) 
    {
        int m = image.size();
        int n = image[0].size();
        vector<vector<bool>> mark(m, vector<bool>(n, false));
        DFS(image, mark, sr, sc, image[sr][sc], color);
        return image;
    }
};

在这里插入图片描述

👉被环绕的区域👈

给你一个 m x n 的矩阵 board ,由若干字符 ‘X’ 和 ‘O’ ,找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。

在这里插入图片描述

思路:通过上图可以发现,如果 ‘O’ 没有被 ‘X’ 环绕了,那么这个 ‘O’ 肯定是在矩阵的四条边上的任意一条。那么,我们可以检查四条边上的点的字符是不是 ‘O’,如果是 ‘O’,我们就将其标记成 ‘A’,说明该字符 ‘O’ 不被 ‘X’ 环绕,然后递归去查找与该点连通的 ‘O’,也将它们改成 ‘A’。那么检查完四条边上的点后,没有被 ‘X’ 环绕的 ‘O’ 都被改成为 ‘A’,需要将它们改回 ‘O’;而被 ‘X’ 环绕的 ‘O’ 还是 ‘O’,需要将它们改成 ‘X’。

class Solution 
{
private:
    int nextPosition[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    void DFS(vector<vector<char>>& board,int X, int Y)
    {
        // 标记此位置的'O'和边上是联通的
        board[X][Y] = 'A';

        // 查找四个方向是否有连通的'O'
        for(int i = 0; i < 4; ++i)
        {
            int newX = X + nextPosition[i][0];
            int newY = Y + nextPosition[i][1];

            // 越界
            if(newX >= board.size() || newX < 0
            || newY >= board[0].size() || newY < 0)
                continue;
            // 递归去查找连通的'O'
            if(board[newX][newY] == 'O')
                DFS(board, newX, newY);
        }
    }

public:
    void solve(vector<vector<char>>& board) 
    {
        int row = board.size();
        int col = board[0].size();

        for(int j = 0; j < col; ++j)
        {
            if(board[0][j] == 'O')
                DFS(board, 0, j);
            if(board[row - 1][j] == 'O')
                DFS(board, row - 1, j);
        }

        for(int i = 1; i < row - 1; ++i)
        {
            if(board[i][0] == 'O')
                DFS(board, i, 0);
            if(board[i][col - 1] == 'O')
                DFS(board, i, col - 1);
        }

        for(int i = 0; i < row; ++i)
        {
            for(int j = 0; j < col; ++j)
            {
                if(board[i][j] == 'A')
                    board[i][j] = 'O';
                else if(board[i][j] == 'O')
                    board[i][j] = 'X';
            }
        }
    }
};

在这里插入图片描述

👉岛屿的周长👈

给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。

网格中的格子 水平和垂直方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。

岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100。计算这个岛屿的周长。

在这里插入图片描述

思路:对于一个陆地格子的每条边,它被算作岛屿的周长当且仅当这条边为网格的边界或者相邻的另一个格子为水域。 因此,我们可以遍历每个陆地格子,看其四个方向是否为边界或者水域,如果是,将这条边的贡献(即 1)加入答案 ret 即可。

深度优先搜索

class Solution 
{
private:
    int nextPosition[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    int DFS(vector<vector<int>>& grid, int X, int Y)
    {
        grid[X][Y] = 2; // 将格子的数改成2,表示该格子的边数已经加过了

        int ret = 0;
        for(int i = 0; i < 4; ++i)
        {
            int newX = X + nextPosition[i][0];
            int newY = Y + nextPosition[i][1];

            // 越界或者上下左右方向是水域,则边数加一
            if(newX < 0 || newX >= grid.size()
            || newY < 0 || newY >= grid[0].size()
            || grid[newX][newY] == 0)
            {
                ret += 1;
                continue;
            }
            else if(grid[newX][newY] == 1)  // 递归求该格子的边数
                ret += DFS(grid, newX, newY);
        }
        return ret;
    }
public:
    int islandPerimeter(vector<vector<int>>& grid) 
    {
        int row = grid.size();
        int col = grid[0].size();

        int ret = 0;
        for(int i = 0; i < row; ++i)
        {
            for(int j = 0; j < col; ++j)
            {
                if(grid[i][j] == 1)
                    ret += DFS(grid, i, j);
            }
        }
        return ret;
    }
};

在这里插入图片描述

迭代

class Solution 
{
private:
    int nextPosition[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

public:
    int islandPerimeter(vector<vector<int>>& grid) 
    {
        int row = grid.size();
        int col = grid[0].size();

        int ret = 0;
        for(int i = 0; i < row; ++i)
        {
            for(int j = 0; j < col; ++j)
            {
                if(grid[i][j] == 1)
                {
                    int count = 0;
                    // 查看该格子的四个方向是不是越界或者水域
                    // 如果是,格子的边数count加一
                    for(int k = 0; k < 4; ++k)
                    {
                        int newI = i + nextPosition[k][0];
                        int newJ = j + nextPosition[k][1];

                        if(newI < 0 || newI >= row
                        || newJ < 0 || newJ >= col
                        || grid[newI][newJ] == 0)
                            ++count;
                    }
                    ret += count;   // 将该格子的边数加到总边数去
                }
            }
        }
        return ret;
    }
};

在这里插入图片描述

👉岛屿的数量👈

给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,
请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

思路:本题的意思是连在一起的陆地都算做一个岛屿,本题可以采用类似渲染的做法,尝试以每个点作为渲染的起点,可以渲染的陆地都算做一个岛屿,最后看渲染了多少次,即深度优先算法执行了多少次。

class Solution 
{
private:
    int nextPosition[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    void DFS(vector<vector<char>>& grid, int X, int Y)
    {
        grid[X][Y] = '2';   // 标记该位置已经查找过了

        for(int i = 0; i < 4; ++i)
        {
            int newX = X + nextPosition[i][0];
            int newY = Y + nextPosition[i][1];
            // 越界
            if(newX < 0 || newX >= grid.size()
            || newY < 0 || newY >= grid[0].size())
                continue;
            // 递归去查找
            if(grid[newX][newY] == '1')
                DFS(grid, newX, newY);
        }
    }
public:
    int numIslands(vector<vector<char>>& grid) 
    {
        int row = grid.size();
        int col = grid[0].size();

        int ret = 0;
        for(int i = 0; i < row; ++i)
        {
            for(int j = 0; j < col; ++j)
            {
                if(grid[i][j] == '1')
                {
                    ++ret;
                    DFS(grid, i, j);
                }
            }
        }
        return ret;
    }
};

在这里插入图片描述

👉岛屿的最大面积👈

给你一个大小为 m x n 的二进制矩阵 grid 。

岛屿是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

思路:本道题也是类似的,最多相邻 1 的个数就是岛屿的最大面积。

class Solution 
{
private:
    int nextPosition[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    int DFS(vector<vector<int>>& grid, int X, int Y)
    {
        grid[X][Y] = 2; // 做标记,表明这块土地已经被查找过了

        int ret = 1;    // 进来就说明至少有一块土地了
        for(int i = 0; i < 4; ++i)
        {
            int newX = X + nextPosition[i][0];
            int newY = Y + nextPosition[i][1];

            if(newX < 0 || newX >= grid.size()
            || newY < 0 || newY >= grid[0].size()
            || grid[newX][newY] == 0)
                continue;
            
            // 递归去查找相邻的土地
            if(grid[newX][newY] == 1)
                ret += DFS(grid, newX, newY);
        }
        return ret;
    }

public:
    int maxAreaOfIsland(vector<vector<int>>& grid) 
    {
        int row = grid.size();
        int col = grid[0].size();

        int Max = 0;
        for(int i = 0; i < row; ++i)
        {
            for(int j = 0; j < col; ++j)
            {
                if(grid[i][j] == 1)
                {
                    int ret = DFS(grid, i, j);
                    Max = ret > Max ? ret : Max;
                }
            }
        }
        return Max;
    }
};

在这里插入图片描述

👉总结👈

本篇讲解了几道 OJ 题,分别是员工的重要性、图像渲染和岛屿问题等。那么以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家!💖💝❣️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/273608.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣SQL刷题4

目录1158. 市场分析 I1280. 学生们参加各科测试的次数1174. 即时食物配送 II585. 2016年的投资1158. 市场分析 I 题型&#xff1a;表1和表2连接时&#xff0c;如何把没有对应数据输出来。即表1中所有id列对应的表2数据输出&#xff0c;没用的输出0 解答1&#xff1a;left join…

【Linux】权限

&#x1f525;&#x1f525; 欢迎来到小林的博客&#xff01;&#xff01;       &#x1f6f0;️博客主页&#xff1a;✈️小林爱敲代码       &#x1f6f0;️博客专栏&#xff1a;Linux之路       &#x1f6f0;️社区&#xff1a; 进步学堂       …

关于软考的一些前期准备

国家软考的中级职称证书&#xff0c;含金量较高且没有报考资质限制 报名时间和考试时间具体请看官网&#xff1a;中国计算机技术职业资格网 不同的资格证书时间和要求不一样&#xff0c;注意查看 上半年&#xff1a; 下半年&#xff1a; 下半年&#xff1a; 软件评测师考试说…

Spring Boot 中事半功倍的一些工具类

系列文章地址&#xff1a;https://blog.csdn.net/perfect2011/article/details/124603278在日常开发中经常有这样那样的小功能需要实现&#xff0c;这些一般会作为工具类存在&#xff0c;在项目中有一些通用的功能&#xff0c;Spring内置了需要工具类&#xff0c;而且经过了大量…

京东一面:20种异步,你知道几种? 含协程

背景说明&#xff1a; 异步&#xff0c;作为性能调优核心方式之一&#xff0c;经常被用于各种高并发场景。 很多场景多会使用到异步&#xff0c;比如&#xff1a; 场景1&#xff1a; 超高并发 批量 写 mysql 、批量写 elasticSearch 场景2&#xff1a; 超高并发 批量 IO 场景…

30分钟掌握 Hive SQL 优化(解决数据倾斜)

Hive SQL 几乎是每一位互联网分析师的必备技能&#xff0c;相信每一位面试过大厂的童鞋都有被面试官问到 Hive 优化问题的经历。所以掌握扎实的 HQL 基础尤为重要&#xff0c;既能帮分析师在日常工作中“如鱼得水”提高效率&#xff0c;也能在跳槽时获得一份更好的工作 offer。…

【23种设计模式】设计模式介绍与分类

前言 本文为 【23种设计模式】设计模式介绍与分类 相关知识介绍&#xff0c;下边将对什么是设计模式&#xff0c;设计模式的分类与23种设计模式的关键点进行详尽介绍~ &#x1f4cc;博主主页&#xff1a;小新要变强 的主页 &#x1f449;Java全栈学习路线可参考&#xff1a;【…

蓝桥算法两周训练营--Day2:DP

T1&#xff1a;P1048 [NOIP2005 普及组] 采药 - 洛谷 代码&#xff1a; 1、二维Dp&#xff1a; package 蓝桥算法两周训练营__普及组.Day2_dp;import java.util.Scanner;/*** author yx* date 2023-02-05 13:16*/ public class t1 {// P1048 [NOIP2005 普及组] 采药 - 洛…

java春招大厂面试,差点让面试官给我聊挂喽!

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01; 八股文整的挺好&#xff0c;算法也刷的够多&#xff0c;但问到项目就很拉胯。 这可能是现在大部分没有实际项目经验的校招生和一直从事边角料开…

环境变量【Linux】

文章目录&#xff1a;Linux环境变量介绍常用的环境变量如何查看环境变量命令搜索路径PATH与环境变量相关的命令环境变量的组织方式通过代码的方式获取环境变量通过系统调用获取或设置环境变量环境变量的全局属性&#xff08;继承&#xff09;Linux环境变量介绍 环境变量&#…

【王道数据结构】第五章(下) | 树 | 二叉树

目录 一、树的存储结构 1、双亲表示法(顺序存储)&#xff1a; 2、孩子表示法(顺序链式) 3、孩子兄弟表示法(链式存储&#xff09; 二、树、森林的遍历 1、树的先根遍历 2、树的后根遍历 3、层序遍历&#xff08;队列实现&#xff09; 4、森林的遍历 三、二叉排序树 …

电子技术——IC偏置-电流源、电流镜、电流舵

电子技术——IC偏置-电流源、电流镜、电流舵 IC偏置设计基于恒流源技术。在IC中的一个特定的区域&#xff0c;会生成一个精确的DC电流&#xff0c;这称为 参考电流 &#xff0c;之后通过电流镜复制到各个所需支路&#xff0c;并且通过电流舵进行电流转向。这项技术为IC的多级放…

知识图谱实战(01):从0-1搭建图片服务器

作者&#xff1a;艾文编程职业&#xff1a;程序员&#xff0c;BAT大厂资深工程师摘要&#xff1a;搜索/推荐场景下给用户展示大量的图片信息&#xff0c;那么这些数据是通过专门的图片服务器来访问的。 我们在基于知识图谱的智能搜索系统中&#xff0c;对搜索出来的每条记录都有…

支付系统核心架构设计思路(万能通用)

文章目录1. 支付系统总览核心系统交互业务图谱2. 核心系统解析交易核心交易核心基础交易类型抽象多表聚合 & 订单关联支付核心支付核心总览支付行为编排异常处理渠道网关资金核算3. 服务治理平台统一上下文数据一致性治理CAS校验幂等 & 异常补偿对账准实时对账DB拆分异…

fpga图像处理(sobel算子)

【声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 关于sobel算子,前面已经讲过计算方法了。一种是上下的sobel算子,一种是左右的sobel算子,两者都相当于prewitt算子的进一步拓展。当然,之前的实现方法都是基于python和opencv实现…

【Leetcode】面试题 16.05. 阶乘尾数、HJ7 取近似值

作者&#xff1a;小卢 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 面试题 16.05. 阶乘尾数 HJ7 取近似值 面试题 16.05. 阶乘尾数 面试题 16.05. 阶乘尾数 …

这才是计算机科学_计算机大量应用

文章目录一、编译原理1.1 早期编译方式1.2 编程语言二、算法&数据结构2.1 Sort2.2 图搜索2.3 Array2.4 Node三、软件工程起源2.1分解打包三 、摩尔定律3.1 发展历3.1.1 电子管3.1.2 晶体管3.1.3 集成电路 IC3.2 刻蚀工艺3.2.2 光刻负责电路一、编译原理 之前讲的例子中 &am…

46 理论计算机科学基础-北京大学

P10 课程介绍05:46P21-1 预备知识07:43P31-2 确定型有穷自动机例子11:23P41-3 确定型有穷自动机的形式化定义17:51P51-4 设计确定型有穷自动机05:57P61-5 正则运算与封闭性28:16P71-6 非确定型有穷自动机37:43P81-7 DFA与NFA的等价性17:41P91-8 正则语言的封闭性10:30P102-1 正…

第九章(13):STL之常用排序算法

文章目录前情回顾常用排序算法sortrandom_shufflemergereverse下一座石碑&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;一名大一的智能制造专业学生&#xff0c;在学习C/C的路上会越走越远&#xff0c;后面不定期更新有关C/C语法&#xff0c;数据结构&#xff0…

Java 面向对象三大特性之三——接口(面试、学习、工作必备技能)

目录 一、接口概述(interface) 二、接口的成员 三、继承和实现 四、单继承和多实现 五、接口的优点 六、接口与抽象类 七、接口的思想 八、接口案例——运动员 ​​​​​​​ 接口概述(interface) 定义&#xff1a;是抽象方法和常量值的集合。 本质&#xff1a;从…