【数据结构和算法】找出叠涂元素

简介: 给你一个下标从0开始的整数数组arr和一个m x n的整数矩阵mat。arr和mat都包含范围[1,m * n]内的所有整数。从下标0开始遍历arr中的每个下标i,并将包含整数arr[i]的mat单元格涂色。请你找出arr中在mat的某一行或某一列上都被涂色且下标最小的元素,并返回其下标i。

其他系列文章导航

Java基础合集

数据结构与算法合集

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

其他系列文章导航

文章目录

前言

一、题目描述

二、题解

三、代码

四、复杂度分析


前言

这是力扣的2661题,难度为中等,解题方案有很多种,本文讲解我认为最奇妙的一种。


一、题目描述

给你一个下标从 0 开始的整数数组 arr 和一个 m x n 的整数 矩阵matarrmat 都包含范围 [1,m * n] 内的 所有 整数。

从下标 0 开始遍历 arr 中的每个下标 i ,并将包含整数 arr[i]mat 单元格涂色。

请你找出 arr 中在 mat 的某一行或某一列上都被涂色且下标最小的元素,并返回其下标 i

示例 1:

image.gif编辑

输入:arr = [1,3,4,2], mat = [[1,4],[2,3]]

输出:2

解释:遍历如上图所示,arr[2] 在矩阵中的第一行或第二列上都被涂色。


示例 2:

image.gif编辑

输入:arr = [2,8,7,4,1,3,5,6,9], mat = [[3,2,5],[1,4,6],[8,7,9]]

输出:3

解释:遍历如上图所示,arr[3] 在矩阵中的第二列上都被涂色。


提示:

    • m == mat.length
    • n = mat[i].length
    • arr.length == m * n
    • 1 <= m, n <= 105
    • 1 <= m * n <= 105
    • 1 <= arr[i], mat[r][c] <= m * n
    • arr 中的所有整数 互不相同
    • mat 中的所有整数 互不相同

    二、题解

    这道题其实是常规哈希表的运用,本题也将用 HashMap 来借题。

    算法:

      • 因为 mat 的值各不相同,将用HashMap来存储,以mat[i][j]也就是值为键,[i,j]也就是坐标为值,方便后续快速查询某个值所在位置。
      • 然后创建数组 c1 和 c2 ,分别用来记录某行某列有多少单元格被涂色,如 c1[x] = a 代表第 x 行被涂色单元格数量为 a 个,c2[y] = b 代表第 y 列被涂色单元格数量为 b 个。
      • 接着遍历所有的 arr[i] ,查询到 arr[i] 的所在位置 info 后,更新 c1 和 c2,若某行或某列被完全涂色,返回当前下标。

      注意题目的意思是:返回刚好涂完一列或一行的时候的最小数字下标。


      三、代码

      Java版本:

      class Solution {
          public int firstCompleteIndex(int[] arr, int[][] mat) {
              int n = mat.length, m = mat[0].length;
              HashMap<Integer, int[]> map = new HashMap<>();
              for (int i = 0; i < n; i++) {
                  for (int j = 0; j < m; j++) {
                      map.put(mat[i][j], new int[]{i, j});//mat[i][j]性质等于arr[i]
                  }
              }
              int[] c1 = new int[n], c2 = new int[m];//c1记录某行单元格涂色情况,c1记录某列单元格涂色情况
              for (int i = 0; i < n * m; i++) {
                  int[] info = map.get(arr[i]);//info[0]是行坐标,[info[1]]是列坐标
                  if (++c1[info[0]] == m || ++c2[info[1]] == n) {
                      return i;//第一个叠涂完成的一定是最小的元素
                  }
              }
              return -1;
          }
      }

      image.gif

      C++版本:

      class Solution {
      public:
          int firstCompleteIndex(vector<int>& arr, vector<vector<int>>& mat) {
              int n = mat.size(), m = mat[0].size();
              unordered_map<int, pair<int, int>> map;
              for (int i = 0; i < n; i++) {
                  for (int j = 0; j < m; j++) {
                      map[mat[i][j]] = make_pair(i, j);
                  }
              }
              vector<int> c1(n), c2(m);
              for (int i = 0; i < n * m; i++) {
                  pair<int, int> info = map[arr[i]];
                  if (++c1[info.first] == m || ++c2[info.secon] == n) return i;
              }
              return -1; // never
          }
      };

      image.gif

      Python版本:

      class Solution:
          def firstCompleteIndex(self, arr: List[int], mat: List[List[int]]) -> int:
              n, m = len(mat), len(mat[0])
              mapping = {mat[i][j]: (i, j) for i in range(n) for j in range(m)}
              c1, c2 = [0] * n, [0] * m
              for i in range(n * m):
                  x, y = mapping[arr[i]]
                  c1[x], c2[y] = c1[x] + 1, c2[y] + 1
                  if c1[x] == m or c2[y] == n: return i
              return -1  # never

      image.gif


      四、复杂度分析

        • 时间复杂度:O(n×m)
        • 空间复杂度:O(n×m)
        目录
        相关文章
        |
        10天前
        |
        存储 算法 Java
        算法系列之数据结构-二叉树
        树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
        42 9
         算法系列之数据结构-二叉树
        |
        7天前
        |
        算法 Java
        算法系列之数据结构-Huffman树
        Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
        32 3
         算法系列之数据结构-Huffman树
        |
        9天前
        |
        算法 Java
        算法系列之数据结构-二叉搜索树
        二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
        54 22
        |
        1月前
        |
        存储 机器学习/深度学习 算法
        C 408—《数据结构》算法题基础篇—链表(下)
        408考研——《数据结构》算法题基础篇之链表(下)。
        94 29
        |
        1月前
        |
        存储 算法 C语言
        C 408—《数据结构》算法题基础篇—链表(上)
        408考研——《数据结构》算法题基础篇之链表(上)。
        107 25
        |
        1月前
        |
        存储 人工智能 算法
        C 408—《数据结构》算法题基础篇—数组(通俗易懂)
        408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
        77 23
        |
        3月前
        |
        存储 运维 监控
        探索局域网电脑监控软件:Python算法与数据结构的巧妙结合
        在数字化时代,局域网电脑监控软件成为企业管理和IT运维的重要工具,确保数据安全和网络稳定。本文探讨其背后的关键技术——Python中的算法与数据结构,如字典用于高效存储设备信息,以及数据收集、异常检测和聚合算法提升监控效率。通过Python代码示例,展示了如何实现基本监控功能,帮助读者理解其工作原理并激发技术兴趣。
        87 20
        |
        2月前
        |
        存储 算法 测试技术
        【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
        本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
        61 2
        |
        5天前
        |
        机器学习/深度学习 算法 数据安全/隐私保护
        基于生物地理算法的MLP多层感知机优化matlab仿真
        本程序基于生物地理算法(BBO)优化MLP多层感知机,通过MATLAB2022A实现随机数据点的趋势预测,并输出优化收敛曲线。BBO模拟物种在地理空间上的迁移、竞争与适应过程,以优化MLP的权重和偏置参数,提升预测性能。完整程序无水印,适用于机器学习和数据预测任务。
        |
        4天前
        |
        资源调度 算法 数据可视化
        基于IEKF迭代扩展卡尔曼滤波算法的数据跟踪matlab仿真,对比EKF和UKF
        本项目基于MATLAB2022A实现IEKF迭代扩展卡尔曼滤波算法的数据跟踪仿真,对比EKF和UKF的性能。通过仿真输出误差收敛曲线和误差协方差收敛曲线,展示三种滤波器的精度差异。核心程序包括数据处理、误差计算及可视化展示。IEKF通过多次迭代线性化过程,增强非线性处理能力;UKF避免线性化,使用sigma点直接处理非线性问题;EKF则通过一次线性化简化处理。