leetcode
leetcode 2251 ~ 2300
找出叠涂元素

找出叠涂元素

难度:

标签:

题目描述

You are given a 0-indexed integer array arr, and an m x n integer matrix mat. arr and mat both contain all the integers in the range [1, m * n].

Go through each index i in arr starting from index 0 and paint the cell in mat containing the integer arr[i].

Return the smallest index i at which either a row or a column will be completely painted in mat.

 

Example 1:

image explanation for example 1
Input: arr = [1,3,4,2], mat = [[1,4],[2,3]]
Output: 2
Explanation: The moves are shown in order, and both the first row and second column of the matrix become fully painted at arr[2].

Example 2:

image explanation for example 2
Input: arr = [2,8,7,4,1,3,5,6,9], mat = [[3,2,5],[1,4,6],[8,7,9]]
Output: 3
Explanation: The second column becomes fully painted at arr[3].

 

Constraints:

  • 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
  • All the integers of arr are unique.
  • All the integers of mat are unique.

代码结果

运行时间: 124 ms, 内存: 37.5 MB


/*
题目思路:
1. 初始化两个数组 rows 和 cols 用于记录每行和每列涂色的单元格数。
2. 使用一个 Map 来存储 mat 中每个数值的坐标位置。
3. 使用 Stream API 来遍历 arr,查找对应数值在 mat 中的位置,并更新 rows 和 cols 数组。
4. 检查当前行或列是否全部涂色,如果是则返回当前索引。
*/

import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;

public class Solution {
    public int firstCompleteIndex(int[] arr, int[][] mat) {
        int m = mat.length;
        int n = mat[0].length;
        int[] rows = new int[m];
        int[] cols = new int[n];
        Map<Integer, int[]> positionMap = new HashMap<>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                positionMap.put(mat[i][j], new int[]{i, j});
            }
        }
        return IntStream.range(0, arr.length).filter(i -> {
            int num = arr[i];
            int[] pos = positionMap.get(num);
            int row = pos[0];
            int col = pos[1];
            rows[row]++;
            cols[col]++;
            return rows[row] == n || cols[col] == m;
        }).findFirst().orElse(-1);
    }
}

解释

方法:

题解的思路是通过建立矩阵元素到其索引的映射,然后通过遍历数组 arr 检查每个元素涂色时矩阵的行或列是否完全涂满。具体来说,首先建立一个 idx 数组,使 idx[v] 存储值 v 在矩阵 mat 中的线性索引。接着,定义两个数组 row_cnt 和 column_cnt 来跟踪每行和每列未被涂色的单元格数量。遍历 arr,每次涂色后更新对应行和列的未涂色计数,一旦某行或某列的计数降至0,即表示该行或列完全涂满,此时返回当前元素的索引。

时间复杂度:

O(m * n)

空间复杂度:

O(m * n)

代码细节讲解

🦆
在建立idx数组时,你是如何确保每个元素的值都能在数组中找到正确的索引?
在建立idx数组时,我通过遍历矩阵mat的每一个元素,并将每个元素的值作为idx数组的索引,其在矩阵中的线性索引作为值。这样,每个元素的值v都直接对应到其在矩阵中的位置(i*n+j),其中i是行索引,j是列索引,n是矩阵的列数。这种映射方式要求矩阵mat中的每个值都是唯一的,且不超过m*n,其中m和n分别是矩阵的行数和列数。
🦆
为什么选择使用单独的row_cnt和column_cnt数组来跟踪未涂色的单元格数量,而不是直接修改mat矩阵?
使用单独的row_cnt和column_cnt数组来跟踪每行和每列的未涂色单元格数量是为了保持原矩阵mat的数据不变,这样可以避免破坏原始数据结构。此外,通过使用这两个计数数组,算法可以更加高效地计算和更新每行和每列的未涂色单元格数量,而直接修改mat矩阵则可能需要更复杂的逻辑来跟踪哪些元素已被修改。
🦆
当row_cnt或column_cnt中某个值减到0时,你是如何确保这一行或一列确实已经完全被涂色的?
当算法中的row_cnt[x]或column_cnt[y]减至0时,这意味着对应的行x或列y的所有单元格都已经被涂色,因为每次在涂色一个单元格时,相应的行和列的计数器都会减1。初始化时,row_cnt数组的每个元素被设置为该行的单元格总数,column_cnt数组的每个元素被设置为该列的单元格总数。因此,当这些计数器减到0,表示对应的行或列的单元格已经完全被涂色。
🦆
在算法中,如果arr数组中的某些值重复出现,会对算法的行为或最终结果产生什么影响?
如果arr数组中的某些值重复出现,算法会对每个出现的值按顺序进行处理,即便这意味着同一个矩阵位置可能被多次考虑涂色。然而,即使重复涂色,行和列的计数器只在首次达到0时影响结果,之后的重复值不会再次触发行或列计数为0的情况。因此,重复的值可能会导致某些不必要的计算,但不会改变首次完全涂满行或列时返回的索引。

相关问题