2711. 对角线上不同值的数量差

题目描述:

给你一个下标从 0 开始、大小为 m x n 的二维矩阵 grid ,请你求解大小同样为 m x n 的答案矩阵 answer 。

矩阵 answer 中每个单元格 (r, c) 的值可以按下述方式进行计算:

令 topLeft[r][c] 为矩阵 grid 中单元格 (r, c) 左上角对角线上 不同值 的数量。
令 bottomRight[r][c] 为矩阵 grid 中单元格 (r, c) 右下角对角线上 不同值 的数量。
然后 answer[r][c] = |topLeft[r][c] - bottomRight[r][c]| 。

返回矩阵 answer 。

矩阵对角线 是从最顶行或最左列的某个单元格开始,向右下方向走到矩阵末尾的对角线。

如果单元格 (r1, c1) 和单元格 (r, c) 属于同一条对角线且 r1 < r ,则单元格 (r1, c1) 属于单元格 (r, c) 的左上对角线。类似地,可以定义右下对角线。

代码思路:

  1. 初始化矩阵:先获取矩阵 grid 的行数 m 和列数 n,接着初始化一个大小同样为 m x n 的答案矩阵 ans,矩阵中所有元素初始值为 0。
  2. 定义辅助函数:定义一个辅助函数 change,它有一个参数 mode,用于区分两种不同的对角线遍历方式:
    • mode = 0:从左下角到右上角遍历对角线。
    • mode = 1:从右下角到左上角遍历对角线。
  3. 遍历对角线:在 change 函数里,依据 mode 的值确定遍历的起始位置,然后用两个字典 top 和 bottom 分别记录左上角和右下角对角线上不同值的数量。
  4. 计算差值:遍历对角线时,更新 top 和 bottom 字典,同时计算每个单元格的左上角和右下角对角线上不同值的数量的差值的绝对值,将其存入答案矩阵 ans 中。
  5. 返回结果:调用 change 函数两次,分别处理两种不同的对角线遍历方式,最后返回答案矩阵 ans

代码实现:

from collections import defaultdict
from typing import List

class Solution:
    def differenceOfDistinctValues(self, grid: List[List[int]]) -> List[List[int]]:
        # 获取矩阵的行数和列数
        m, n = len(grid), len(grid[0])
        # 初始化答案矩阵,所有元素初始值为 0
        ans = [[0] * n for _ in range(m)]
        
        def change(mode=0): # mode=0,左下-右下;mode=1,后下-右上
            # 根据 mode 的值确定遍历的起始位置
            LOOP = range(n) if mode == 0 else range(m-2, -1, -1)
            for j in LOOP:
                # 初始化两个字典,用于记录左上角和右下角对角线上不同值的数量
                top = defaultdict(int)
                bottom = defaultdict(int)
                # 根据 mode 的值确定起始位置
                if mode == 0:
                    r, s = m-1, j
                else:
                    r, s = j, n-1
                # 遍历左上角对角线,统计不同值的数量
                while r >= 0 and s >= 0: 
                    top[grid[r][s]] += 1
                    r -= 1
                    s -= 1

                # 重置起始位置
                if mode == 0:
                    r, s = m-1, j
                else:
                    r, s = j, n-1
                # 遍历对角线,更新 top 和 bottom 字典,计算差值并更新答案矩阵
                while r >= 0 and s >= 0: 
                    d = grid[r][s]
                    top[d] -= 1
                    if top[d] == 0:
                        del top[d]
                    ans[r][s] = abs(len(top)-len(bottom))
                    bottom[d] += 1
                    r -= 1
                    s -= 1
        # 处理左下角到右上角的对角线
        change(0)
        # 处理右下角到左上角的对角线
        change(1)

        return ans

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值