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

周赛 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(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(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(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(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(nm·lg(nm))$ 瓶颈在排序
  • 空间复杂度:$O(nm)$

往期回顾

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

  1. Leetcode 673.最长递增子序列的个数

    最长递增子序列的个数 给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[ ...

  2. 【LeetCode动态规划#14】子序列系列题(最长递增子序列、最长连续递增序列、最长重复子数组、最长公共子序列)

    最长递增子序列 力扣题目链接(opens new window) 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度. 子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其 ...

  3. [LeetCode] Longest Increasing Path in a Matrix 矩阵中的最长递增路径

    Given an integer matrix, find the length of the longest increasing path. From each cell, you can eit ...

  4. [LeetCode] Longest Increasing Subsequence 最长递增子序列

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

  5. [LeetCode] 300. Longest Increasing Subsequence 最长递增子序列

    Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Inp ...

  6. [leetcode]300. Longest Increasing Subsequence最长递增子序列

    Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Inp ...

  7. leetcode最长递增子序列问题

    题目描写叙述: 给定一个数组,删除最少的元素,保证剩下的元素是递增有序的. 分析: 题目的意思是删除最少的元素.保证剩下的元素是递增有序的,事实上换一种方式想,就是寻找最长的递增有序序列.解法有非常多 ...

  8. Java实现 LeetCode 673 最长递增子序列的个数(递推)

    673. 最长递增子序列的个数 给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, ...

  9. Java实现 LeetCode 583 两个字符串的删除操作(求最长公共子序列问题)

    583. 两个字符串的删除操作 给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符. 示例: 输入: " ...

  10. 【LeetCode】300.最长递增子序列——暴力递归(O(n^3)),动态规划(O(n^2)),动态规划+二分法(O(nlogn))

    算法新手,刷力扣遇到这题,搞了半天终于搞懂了,来这记录一下,欢迎大家交流指点. 题目描述: 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度. 子序列是由数组派生而来的序列,删除(或不删 ...

随机推荐

  1. 有关驱动与应用层数据交互的小例子( 以及驱动 epoll 实现的实现方式 )

    介绍 演示了一个驱动对应多个设备,以及各个设备的存取 演示了应用与驱动,mmap 的映射实现与访问 演示了应用层通过 select, poll, epoll 方式读写设备数据 netlink 的方式待 ...

  2. 2020中国最好大学排名.py(亲测有效)

    import requests from bs4 import BeautifulSoup import bs4 def getHTMLText(url): try: r = requests.get ...

  3. ArcMap安装OSM路网数据编辑插件ArcGIS Editor for OSM的方法

      本文介绍在ArcGIS下属的ArcMap软件中,ArcGIS Editor for OpenStreetMap这一工具集插件的下载与安装的具体方法.   ArcGIS Editor for Ope ...

  4. opencv-python 4.9.2. 轮廓特征

    矩 图像的矩可帮助你计算某些特征,如对象的质心,对象的面积等特征.函数cv.moments()给出了计算的所有矩值的字典. 从这一刻起,你可以提取有用的数据,如面积,质心等.质心由关系给出, $$ C ...

  5. 什么时候需要使用try-catch

    代码执行预料不到的情况,或出错的可能性很大时,使用try-catch语句 构造一个文件输入流(上传文件时,线上环境的内存情况不确定)出错的可能性很大 文件上传写入, 数据库事务的提交,还有摄像头和打印 ...

  6. What's the best way to read and understand someone else's code?

    Find one thing you know the code does, and trace those actions backward, starting at the end Say, fo ...

  7. 存储系统模拟—R实现

    存储系统 存储问题是人们最熟悉又最需要研究的问题之一.例如企业储存的原材料.在制品等,存储太少,不足以满足生产的需要,将使生产过程中断; 存储太多,超过了生产的需要,将造成资金及资源的积压浪费.商店储 ...

  8. MYSQL5.7.30安装

    1.下载MySQL 我用的是5.7.30(安装版) 我选择的下载链接:https://dev.mysql.com/downloads/windows/installer/5.7.html 官网链接:h ...

  9. [数据库]Ubuntu Linux/Kylin: 安装MySQL

    1 文由 由于安装环境较为特殊,实在折煞人也.而此环境的网络博客/教程偏少,觉得有必要记录一下. 2 环境 安装主机不支持联网 即 不支持APT/APT-GET等傻瓜式的在线安装方式. 硬件架构: A ...

  10. 11.spring security 认证和授权简单流程了解

    1.总结:昨天主要是对WebSecurityConfigurerAdaptor的三个函数的区分以及了解了spring security的认证和授权流程:再就是动手使用了下thymeleaf和freeM ...