当前位置: 首页 > news >正文

[M模拟] lc2711. 对角线上不同值的数量差(对角线遍历+前后缀分解)

文章目录

    • 1. 题目来源
    • 2. 题目解析

1. 题目来源

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

前置题:

  • [M模拟] lc3446. 按对角线进行矩阵排序(对角线遍历+公式推导+模板题)
    • 矩形的对角线遍历的基础题。

题单:

  • 待补充

2. 题目解析

2025年03月25日21:21:28

方法一:暴力

  • 由于这个题目数据量太小了哈,就完全可以暴力来做,每次去暴力判断下左上侧、右下侧对角线的重复元素个数即可。

方法二:前后缀分解

  • 暴力显然在同一个对角线上有很多元素被重复遍历。
  • 这个时候就需要对角线的前后缀分解。确保重复遍历次数较少。
    • 直接遍历每一条对角线元素。
    • 从左上方到右下方这样的遍历方向。
    • 同时统计左上方对角线的不同元素个数。作为前缀统计,直接放到答案中。
    • 再从右下方到左上方这样的遍历方向。
    • 此时就可以直接计算答案了,同时统计 右下方 到 左上方 对角线的不同元素个数。作为后缀统计,直接与前缀元素计算答案即可。
  • 所以,每个元素至多被遍历两遍。

方法三:状态压缩+前后缀分解

  • 这个没啥难度哈,一个简单的状态压缩,将 set 使用一个 uint64 的数字进行代替,是完全可以的哈。
  • 注意里面一些位运算的 API 和技巧 即可。

  • 时间复杂度 O ( n m ) O(nm) O(nm)
  • 空间复杂度 O ( 1 ) O(1) O(1) 返回值不计算

方法二:前后缀分解

func differenceOfDistinctValues(grid [][]int) [][]int {
    n, m := len(grid), len(grid[0])
    res := make([][]int, n)
    for i := range n {
        res[i] = make([]int, m)
    }
    set := map[int]struct{}{}
    for k := 1; k < n + m; k ++ {
        minJ, maxJ := max(0, m - k), min(m - 1, n - 1 - k + m)
        
        clear(set)        
        for j := minJ; j <= maxJ; j ++ {    // 处理前缀
            i := j + k - m
            res[i][j] = len(set)            // 不包含(i, j) 注意顺序
            set[grid[i][j]] = struct{}{}   
        }

        clear(set)
        for j := maxJ; j >= minJ; j -- {   // 处理后缀,计算答案
            i := j + k - m
            res[i][j] = abs(res[i][j] - len(set))
            set[grid[i][j]] = struct{}{}
        }
    }
    
    return res
}

func abs(x int) int { 
    if x < 0 { 
        return -x 
    } 
    return x 
}

方法一:暴力

func differenceOfDistinctValues(grid [][]int) [][]int {
    n, m := len(grid), len(grid[0])
    res := make([][]int, n)
    for i := range n {
        res[i] = make([]int, m)
    }

    getL := func(x, y int) int {
        s := map[int]struct{}{}
        x -- 
        y -- 
        for x >= 0 && y >= 0 {
            s[grid[x][y]] = struct{}{}
            x --
            y --
        }

        return len(s)
    }

    getR := func(x, y int) int {
        s := map[int]struct{}{}
        x ++ 
        y ++ 
        for x < n && y < m {
            s[grid[x][y]] = struct{}{}
            x ++
            y ++
        }

        return len(s)
    }
    abs := func(x int) int {
        if x > 0 {
            return x
        }

        return -x
    }

    for i := range n {
        for j := range m {
            res[i][j] = abs(getL(i, j) - getR(i, j))
        }
    }

    return res
}

相关文章:

  • Python条件处理,新手入门到精通
  • 【系统架构设计师】软件质量管理
  • 常见电子元器件介绍
  • Ollama Embedding模型运行与使用
  • Bluetooth Beacons的介绍和技术实现
  • 基于动态 FOF(基金中的基金)策略的基金交易推荐系统的设计与实现思路
  • 【QT】 布局器
  • LDAP安装和基本使用
  • Android Launcher实战:完美复刻iOS风格Hotseat布局优化
  • Clio:具备锁定、用户认证和审计追踪功能的实时日志记录工具
  • Redis原理: List BRPOP分析
  • Android开发代码中设置Margin
  • Docker安装 Nacos 微服务
  • 【WebGIS教程1】WebGIS学习初步知识了解 · 概述
  • Allpaires正交表工具使用
  • Codeforces Round 1003 (Div. 4)
  • 心房颤动新机制:ATM/p53通路早期抑制
  • 最新DeepSeek-V3-0324:AI模型性能提升与新特性解析
  • Xshell远程登录腾讯云高性能应用服务
  • 2.基于多线程的TCP服务器实现
  • 东营市报名系统网站设计公司/百度首页推荐关不掉吗
  • 找装修公司去哪个网站/购买域名后如何建立网站
  • 网站建设补充协议模板/今日新闻最新头条10条
  • 网站是否wordpress/餐饮培训
  • 前端网页/seo服务价格表
  • 自己建设网站的利弊/百度知道在线问答