LeetCode 周赛 347(2023/05/28)二维空间上的 LIS 最长递增子序列问题

news2024/12/28 6:04:18

本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。

  • 往期回顾:LeetCode 单周赛第 346 场 · 仅 68 人 AK 的最短路问题

周赛 347 概览

T1. 移除字符串中的尾随零(Easy)

  • 标签:模拟、字符串

T2. 对角线上不同值的数量差(Easy)

  • 标签:前后缀分解

T3. 使所有字符相等的最小成本(Medium)

  • 标签:模拟、贪心

T4. 矩阵中严格递增的单元格数(Hard)

  • 标签:排序、动态规划


T1. 移除字符串中的尾随零(Easy)

https://leetcode.cn/problems/remove-trailing-zeros-from-a-string/

题解(模拟)

基于 StringBuilder:

class Solution {
    fun removeTrailingZeros(num : String): String {
        if (num.length == 1) return num
        val builder = StringBuilder(num)
        while (builder.last() == '0') {
            builder.deleteCharAt(builder.lastIndex)
        }
        return builder.toString()
    }
}

基于正则表达式匹配:

class Solution {
    fun removeTrailingZeros(num : String): String {
        return num.replace(Regex("0*$"), "")
    }
}

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1) 不考虑结果字符串

T2. 对角线上不同值的数量差(Easy)

https://leetcode.cn/problems/difference-of-number-of-distinct-values-on-diagonals/

题解(前后缀分解)

第一次扫描增加正权,第二次扫描增加负权:

class Solution {
    fun differenceOfDistinctValues(grid: Array<IntArray>): Array<IntArray> {
        // 两次扫描
        val n = grid.size
        val m = grid[0].size
        val ret = Array(n) { IntArray(m) }
        
        for (row in 0 until n) {
            var i = row
            var j = 0
            val set = HashSet<Int>()
            while (i < n && j < m) {
                ret[i][j] += set.size
                set.add(grid[i][j])
                i++
                j++
            }
        }
        
        for (col in 1 until m) {
            var i = 0
            var j = col
            val set = HashSet<Int>()
            while (i < n && j < m) {
                ret[i][j] = set.size
                set.add(grid[i][j])
                i++
                j++
            }
        }

        for (row in 0 until n) {
            var i = row
            var j = m - 1
            val set = HashSet<Int>()
            while (i >= 0 && j >= 0) {
                ret[i][j] = Math.abs(ret[i][j] - set.size)
                set.add(grid[i][j])
                i--
                j--
            }
        }
        
        for (col in 0 until m - 1) {
            var i = n - 1
            var j = col
            val set = HashSet<Int>()
            while (i >= 0 && j >= 0) {
                ret[i][j] = Math.abs(ret[i][j] - set.size)
                set.add(grid[i][j])
                i--
                j--
            }
        }
        return ret
    }
}

复杂度分析:

  • 时间复杂度: O ( n m ) O(nm) O(nm)
  • 空间复杂度: O ( n m ) O(nm) O(nm)

T3. 使所有字符相等的最小成本(Medium)

https://leetcode.cn/problems/minimum-cost-to-make-all-characters-equal/

题解一(模拟)

从中间开始翻转,将不符合目标的字符向两端推,选择反转到 ‘1’ 和 ‘0’ 两个方案的最优解:

class Solution {
    
    private fun op(s:String, target:Char) :Long {
        val n = s.length
        var ret = 0L
        var flag = true
        for (i in n / 2 - 1 downTo 0) {
            if ((flag && s[i] != target) || (!flag && s[i] == target)) {
                ret += i + 1
                flag = !flag
            }
        }
        flag = true
        for (i in n / 2 until n) {
            if ((flag && s[i] != target) || (!flag && s[i] == target)) {
                ret += n - i
                flag = !flag
            }
        }
        return ret
    }
    
    fun minimumCost(s: String): Long {
        return Math.min(op(s,'0'), op(s,'1'))
    }
}

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

题解二(找规律)

当相邻字符串不相等时,必然需要反转。如果接近左边往左边翻转的成本更低,同时,如果接近右边,往右边翻转的成本更低。

class Solution {
    fun minimumCost(s: String): Long {
        val n = s.length
        var ret = 0L
        for (i in 1 until n) {
            if (s[i - 1] != s[i]) {
                ret += Math.min(i, n - i)
            }
        }
        return ret
    }
}

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

T4. 矩阵中严格递增的单元格数(Hard)

https://leetcode.cn/problems/maximum-strictly-increasing-cells-in-a-matrix/
  • 错误思路:

从最大值开始逆向推导,但是最优路径不一定会经过最大值。

  • 正确思路:

只有小的数字才能到大的数字,因此我们先将所有数字进行排序,对于每个数字储存其对应的所有位置。此时,每个位置的 LIS 最长序列长度只跟其排序前面的数字中位于同行和同列的数字有关,即前面数字且处于同行同列的最长路径 + 1。

class Solution {
    fun maxIncreasingCells(mat: Array<IntArray>): Int {
        val n = mat.size
        val m = mat[0].size
        var ret = 0
        // 排序
        val map = TreeMap<Int, MutableList<IntArray>>()
        for (i in 0 until n) {
            for (j in 0 until m) {
                map.getOrPut(mat[i][j]) { LinkedList<IntArray>() }.add(intArrayOf(i, j))
            }
        }
        val rowMax = IntArray(n)
        val colMax = IntArray(m)
        // 枚举
        for ((x, indexs) in map) {
            val mx = IntArray(indexs.size)
            // LIS
            for (i in indexs.indices) {
                mx[i] = Math.max(rowMax[indexs[i][0]], colMax[indexs[i][1]]) + 1
                ret = Math.max(ret, mx[i])
            }
            for (i in indexs.indices) {
                rowMax[indexs[i][0]] = Math.max(rowMax[indexs[i][0]], mx[i])
                colMax[indexs[i][1]] = Math.max(colMax[indexs[i][1]], mx[i])
            }
        }
        return ret
    }
}

复杂度分析:

  • 时间复杂度: O ( n m ⋅ l g ( n m ) ) O(nm·lg(nm)) O(nmlg(nm)) 瓶颈在排序
  • 空间复杂度: O ( n m ) O(nm) O(nm)

往期回顾

  • LeetCode 单周赛第 346 场 · 仅 68 人 AK 的最短路问题
  • LeetCode 单周赛第 345 场 · 体验一题多解的算法之美
  • LeetCode 双周赛第 104 场 · 流水的动态规划,铁打的结构化思考
  • LeetCode 双周赛第 103 场 · 区间求和的树状数组经典应用

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

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

相关文章

HTTP协议深入理解+如何使用Fiddler抓包

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 目录 文章目录 一、HTTP概述 1.1 什么是HTTP 1.2 理解应用层协议 二、抓包工具fiddler的使用 2.1 几个需要注意的点 2.2 fiddler的原理 2.3 fiddler的使用技巧 三、HTTP请求&#xff08;Re…

intel驱动程序和支持助理常见问题:不识别、无法检测等问题解决方法

起因&#xff1a; wifi驱动有点问题&#xff0c;于是想着更新一下官方的驱动&#xff0c;下载intel驱动程序和支持助理并安装完成后&#xff0c;打开成了这个样子&#xff0c;刷新多少次都没有用&#xff0c;就是不识别。 解决方法&#xff1a; 经过一波胡乱操作&#xff0…

华为OD机试之真正的密码(Java源码)

真正的密码 题目描述 一行中输入一个字符串数组&#xff0c;如果其中一个字符串的所有以索引0开头的子串在数组中都有&#xff0c;那么这个字符串就是潜在密码在所有潜在密码中最长的是真正的密码&#xff0c;如果有多个长度相同的真正的密码&#xff0c;那么取字典序最大的为…

使用CompletionService进行多个文件打包为zip下载

最近没怎么写博客了&#xff0c;因为前段时间在准备软考复习&#xff0c;昨天考完试&#xff0c;现在总算轻松一点了&#xff0c;有更多自由的时间了&#xff0c;总结一下JUC包下的一些并发工具类&#xff0c;主要是从使用场景入手。 CompletionService可以用于实现任务并行化…

数据结构入门(C语言版)图的概念和功能函数实现

图的概念和功能函数实现 前言1.图的定义和术语1.1 定义1.2 常用术语 2.图的存储结构2.1 图的数组(邻接矩阵)存储表示2.2 图的邻接表存储表示 3.图的遍历3.1 深度优先搜索3.2 广度优先搜索3.3 示例 4.连通网的最小生成树4.1 克鲁斯卡尔(Kruskal)算法4.2 普里姆(Prim)算法 5.图的…

企业云盘软件世界排行榜:提升企业文件管理效率的最佳工具

企业云盘是一种面向企业用户提供的在线存储和文件分享服务&#xff0c;它能够帮助企业实现数据备份、文件共享、办公协同等多种功能。通过企业云盘&#xff0c;企业可以将数据集中管理&#xff0c;避免了传统存储方式的不便和风险。 企业云盘的优势 1. 集中管理&#xff1a;企业…

【js】对象属性的拦截和Proxy代理与Reflect映射的用法与区别

✍️ 作者简介: 前端新手学习中。 &#x1f482; 作者主页: 作者主页查看更多前端教学 &#x1f393; 专栏分享&#xff1a;css重难点教学 Node.js教学 从头开始学习 ajax学习 文章目录 对象属性的拦截介绍SetGet 对象的拦截介绍使用对象属性拦截和对象拦截区别练习题 映射…

【Python实战】Python采集地震信息

前言 昨天,我们这里发生了地震,不过,没有太大的问题,我就想着能不能把近几年发生地震的信息,收集下来,我们发现中国地震台网的官方微博会分布近几年发生地震的信息。我们可以直接在这里获取。 环境使用 python 3.9pycharm模块使用 requests模块介绍 requests requ…

每日一博 - 浅析事务隔离级别 MVCC机制

文章目录 DB四个隔离级别MVCC如何工作的 &#xff1f;小结 DB四个隔离级别 数据库隔离允许事务执行&#xff0c;就像没有其他并发运行的事务一样。 下面的图说明了四个隔离级别。 Serializalble: 这是最高的隔离级别。并发交易保证按顺序执行。Repeatable Read: 事务开始时读…

Flutter 笔记 | Flutter 事件与通知

原始指针事件处理 命中测试 在移动端&#xff0c;各个平台或UI系统的原始指针事件模型基本都是一致&#xff0c;即&#xff1a;一次完整的事件分为三个阶段&#xff1a;手指按下、手指移动、和手指抬起&#xff0c;而更高级别的手势&#xff08;如点击、双击、拖动等&#xf…

重学迭代器和生成器

重学迭代器和生成器 之前在 JavaScript 高级程序设计第 7 章 迭代器和生成器 学习笔记 其实包含过 iterator 和 generator 的学习笔记&#xff0c;不过依旧温故而知新&#xff0c;有了一些实际上手的经验后重新再回滚一边会有比较深刻的理解&#xff0c;而不是只是 cv 书上的内…

硬件基础常识【3】--详细说说贴片电容器,可能有你不知道的

目录 贴片电容介绍MLCC的制作过程电容失效的头号大敌电容失效的最主要原因电容的容值、耐压值与封装尺寸的关系 电容串并联串联并联 电容的等效电路选取电容的建议总结 贴片电容介绍 贴片电容相信干电子技术活的基本都使用过&#xff0c;他的全称为&#xff1a;多层片式陶瓷电…

基础学习——读txt数据、字符串转list或数组、画PR曲线、画Loss曲线

文章目录 字符串转数组字符串中的数组转列表转整数列表 读数据&#xff0c;然后画PR曲线读取txt数据关于PR曲线代码 读数据画Loss曲线读txt数据代码 字符串转数组 .split() 是Python中的一个字符串方法&#xff0c;它可以将一个字符串按照指定的分隔符分割成多个子字符串&…

智能工厂 | 联合汽车电子有限公司汽车驱动科技上海智能工厂

智能制造是我国加快建设制造强国的主攻方向&#xff0c;是上海城市数字化转型的重要抓手。智能工厂是推动智能制造的切入点和突破口&#xff0c;是制造业数字化转型的重要载体&#xff0c;以智能工厂为载体布局新赛道、触发新动能、带动新终端&#xff0c;从而实现制造业高质量…

scanf读取字符数组的注意点

起因&#xff1a;scanf的%c格式可以读取空格和回车 读取中间无空格隔开的二维字符数组时 #include<bits/stdc.h> using namespace std; char mp[10][10]; signed main() {for(int i1;i<3;i){for(int j1;j<3;j){scanf("%c",&mp[i][j]);}getchar();/…

Zookeeper集群 + Kafka集群

Zookeeper 概述 Zookeeper 定义 Zookeeper是一个开源的分布式的&#xff0c;为分布式框架提供协调服务的Apache项目。 Zookeeper 工作机制 Zookeeper从设计模式角度来理解&#xff1a;是一个基于观察者模式设计的分布式服务管理框架&#xff0c;它负责存储和管理大家都关心的…

液体压强、浮力与密度分析

如图所示&#xff0c;将甲、乙两个容器放在水平桌面上&#xff0c;甲、乙两容器的底面积为S甲&#xff0c;S乙&#xff0c;甲容器中盛有密度为p1的液体&#xff0c;乙容器中盛有密度为p2的液体。现将体积相等的A、B两个物体分别放入甲、乙两容器后&#xff0c;物体A悬浮&#x…

学习TypeScript快速入门

&#x1f341; 作者主页&#xff1a;&#x1f496;仙女不下凡&#x1f496; &#x1f341; 前言介绍&#xff1a;以下&#x1f447; 内容是根据“阿宝哥”的教材自学总结&#xff0c;定期更新欢迎持续关注&#xff01; &#x1f341; 学习前提&#xff1a;学习该文章之前需要…

数据在内存中的存储(1)——整形

目录 1、数据类型介绍 1.1、类型的基本归类 整形家族 浮点数家族 指针类型 空类型 构造类型 2、整形在内存中的存储 2.1、原码、反码、补码 2.2、大小端介绍 2.3、有符号与无符号 2.4、练习 例一 例二 例三 例四 例五 1、数据类型介绍 我们先来简单了解一下我们前面所学的基…

【腾讯云Finops Crane集训营】降本增效之 Crane 初体验

1. Crane 初识2. Crane 如何进行成本优化&#xff1f;3. Crane 快速上手体验3.1 安装 Prometheus 和 Grafana3.2 安装 Crane 和 Fadvisor3.3 验证安装是否成功3.4 访问 Dashboard 4. Crane 初体验 - 总结&建议5. 关于腾讯云 Finops Crane 集训营 最近有幸参加了腾讯云 Fino…