LeetCode 双周赛 106(2023/06/10)两道思维题

这篇具有很好参考价值的文章主要介绍了LeetCode 双周赛 106(2023/06/10)两道思维题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

  • 往期回顾:LeetCode 单周赛第 348 场 · 数位 DP 模版学会了吗?

双周赛 106 概览

T1. 判断一个数是否迷人(Easy)

  • 标签:计数

T2. 找到最长的半重复子字符串(Medium)

  • 标签:同向双指针

T3. 移动机器人(Medium)

  • 标签:脑筋急转弯、排序

T4. 找到矩阵中的好子集(Hard)

  • 标签:散列表、贪心

T1. 判断一个数是否迷人(Easy)

https://leetcode.cn/problems/check-if-the-number-is-fascinating/description/

题解一(计数)

  • 计算拼接后的数字,并检查数字 1 到 9 的数量是否为 1,可以用字符串比较来模拟计数;
  • 观察数字规律,合法 n 的有效范围是 [123, 329]。
class Solution {
    fun isFascinating(n: Int): Boolean {
        if (n !in 123..329) return false
        return "123456789" == "$n${2*n}${3*n}".asSequence().sorted().joinToString("")
    }
}

复杂度分析:

  • 时间复杂度:O(UlgU) U 是单个数字的最大长度
  • 空间复杂度:O(U)

题解二(打表)

题目范围中只有 4 个迷人数。

class Solution {
    fun isFascinating(n: Int): Boolean {
        return n in arrayOf(192, 219, 273, 327)
    }
}

复杂度分析:

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

T2. 找到最长的半重复子字符串(Medium)

https://leetcode.cn/problems/find-the-longest-semi-repetitive-substring/

题解(同向双指针)

维护滑动窗口,如果右指针与前一个位置相同,说明增加一个相邻重复对。

当相邻重复对 repeatCnt 大于 1 时,此时需要收缩左指针,如果左指针与右边后一个位置相同,说明减少一个相邻重复对(由于 repeatCnt 大于 1 时左指针不可能超过窗口,所以不需要检查左指针移动越界)。

class Solution {
    fun longestSemiRepetitiveSubstring(s: String): Int {
        val n = s.length
        var ret = 0
        var i = 0
        var repeatCnt = 0
        for (j in 0 until n) {
            // 移动右指针
            if (j > 0 && s[j] == s[j - 1]) repeatCnt ++
            while (repeatCnt > 1) {
                // 移动左指针
                if (s[i] == s[i + 1]) repeatCnt --
                i++
            }
            // 记录结果
            ret = Math.max(ret, j - i + 1)
        }
        return ret
    }
}

复杂度分析:

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

T3. 移动机器人(Medium)

https://leetcode.cn/problems/movement-of-robots/

题解(模拟 + 排序)

注意到当发生碰撞而改变机器人方向时,我们可以对调机器人身份,此时等价于没有发生碰撞且机器人按照正常方向行驶,因此我们可以直接忽视碰撞规则,计算机器人的最终位置并计算两两距离。

为了计算两两距离,我们先对所有点排序。由于两个机器人的距离公式是 x - y,那么对于每个机器人 nums[i],在距离公式中它将作为 i 次 x 做加法,以及作为 (n -1 - i) 次 y 做解法,可以枚举每个机器人对距离公式的贡献度而算出整体的两两距离和。

class Solution {
    fun sumDistance(nums: IntArray, s: String, d: Int): Int {
        val n = nums.size
        val MOD = 1000000007
        // 移动(忽视碰撞)
        for (i in nums.indices) {
            nums[i] += if (s[i] == 'R') d else -d
        }
        // 排序
        nums.sort()
        // 计算两两距离
        var ret = 0L
        for (i in nums.indices) {
            ret = (ret + (2L * i - n + 1) * nums[i]) % MOD
        }
        return ret.toInt()
    }
}

复杂度分析:

  • 时间复杂度:O(nlgn) 瓶颈在排序
  • 空间复杂度:O(lgn)

相似题目:

  • 1503. 所有蚂蚁掉下来前的最后一刻

T4. 找到矩阵中的好子集(Hard)

https://leetcode.cn/problems/find-a-good-subset-of-the-matrix/

题解(散列 + 贪心)

容易想到,我们需要选择出 1 相对稀疏的那些行(但不一定是最稀疏的行),而且重复选择完全相同的行不会对结果产生价值,所以我们先对行去重。

由于题目最多只有5 列,所有最多只有 2^5=32 种行类型,可以证明题目在 n = 5 的情况下,有效解最多只有 2 行。

class Solution {
    fun goodSubsetofBinaryMatrix(grid: Array<IntArray>): List<Int> {
        val n = grid.size
        val m = grid[0].size
        // 分组
        val U = 32 // 0 - 31
        val indexs = IntArray(U) { -1 }
        for ((i, row) in grid.withIndex()) {
            var mask = 0
            for ((j, e) in row.withIndex()) {
                mask = mask or (e shl j)
            }
            indexs[mask] = i
        }
        // 全 0
        if (-1 != indexs[0]) return listOf(indexs[0])
        // 贪心
        for (x in 1 until U) {
            for (y in 1 until U) {
                // 过滤
                if (-1 == indexs[x] || -1 == indexs[y]) continue
                // 是否互补
                if (x and y == 0) return listOf(indexs[x], indexs[y]).sorted()
            }
        }
        return Collections.emptyList()
    }
}

复杂度分析:文章来源地址https://www.toymoban.com/news/detail-479047.html

  • 时间复杂度:O(n + U^2) U = 32
  • 空间复杂度:O(U)

往期回顾

  • LeetCode 单周赛第 348 场 · 数位 DP 模版学会了吗?
  • LeetCode 单周赛第 347 场 · 二维空间上的 LIS 最长递增子序列问题
  • LeetCode 双周赛第 104 场 · 流水的动态规划,铁打的结构化思考
  • LeetCode 双周赛第 103 场 · 区间求和的树状数组经典应用

到了这里,关于LeetCode 双周赛 106(2023/06/10)两道思维题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [LeetCode周赛复盘] 第 111 场双周赛20230819

    T1 对向双指针。 T2 子序列/同向双指针。 T3 LIS/状态DP。 T4 数位DP。 2824. 统计和小于目标的下标对数目 1. 题目描述 2. 思路分析 类似两数之和,由于顺序无关,把数据排序。 设置l,r=0,n-1。 若a[l]+a[r]target,则a[l]+ 任意a[l+1…r]都target。则这r-l个数都可以和l组队。 3. 代码实现 2825

    2024年02月11日
    浏览(38)
  • 第 107 场LeetCode双周赛

    A 最大字符串配对数目 显然各字符串对 间匹配的先后顺序不影响最大匹配数目, 可以从后往前遍历数组, 判断前面是否有和当前末尾构成匹配的. B 构造最长的新字符串 记忆化搜索: 定义状态 p a a , b b , a b , l a s t p_{aa,bb,ab,last} p aa , bb , ab , l a s t ​ 为剩余三种字符串分别为aa、

    2024年02月11日
    浏览(33)
  • leetcode第124场双周赛

    给你一个整数数组  nums  ,如果  nums   至少  包含  2  个元素,你可以执行以下操作: 选择  nums  中的前两个元素并将它们删除。 一次操作的  分数  是被删除元素的和。 在确保  所有操作分数相同  的前提下,请你求出  最多  能进行多少次操作。 请你返回按照上述

    2024年02月19日
    浏览(30)
  • LeetCode---121双周赛---数位dp

    2996. 大于等于顺序前缀和的最小缺失整数 2997. 使数组异或和等于 K 的最少操作次数 2998. 使 X 和 Y 相等的最少操作次数 2999. 统计强大整数的数目 简单的模拟题,只要按照题目的要求去写代码即可,代码如下 这题考异或的性质---相同为0,相异为1,我们只要关心nums的异或和与

    2024年01月22日
    浏览(42)
  • leetcode 122双周赛 解题思路+代码

    本人水平有限,只做出3道,最后1道放弃。 给你一个长度为 n 的整数数组 nums 。 一个数组的 代价 是它的 第一个 元素。比方说,[1,2,3] 的代价是 1 ,[3,4,1] 的代价是 3 。 你需要将 nums 分成 3 个 连续且没有交集 的子数组。 请你返回这些子数组的 最小 代价 总和 。 示例 1: 输

    2024年02月20日
    浏览(35)
  • [LeetCode108双周赛&LeetCode353周赛] 学习用记忆化搜索解决 DP 问题

    参考灵神直播和代码 @cache 装饰器的作用:将传入不同参数得到的函数值存储到缓存,避免下次传递相同参数重复计算结果,可用于解决递归函数重复计算问题,比如递归求斐波那契问题。 https://leetcode.cn/problems/maximum-number-of-jumps-to-reach-the-last-index/ 记忆化搜索 dfs(i) 表示以

    2024年02月13日
    浏览(27)
  • 第 122 场 LeetCode 双周赛题解

    A 将数组分成最小总代价的子数组 I 枚举:枚举后两个子数组的起始下标 B 判断一个数组是否可以变为有序 模拟:模拟冒泡排序的过程,若相邻元素大小关系需要交换位置,但其二进制下数位为 1 的数目不同,则返回false,若完成排序返回true C 通过操作使数组长度最小 脑筋急

    2024年01月22日
    浏览(30)
  • LeetCode 双周赛 101,DP/中心位贪心/裴蜀定理/Dijkstra/最小环

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。 大家好,我是小彭。 这周比较忙,上周末的双周赛题解现在才更新,虽迟但到哈。上周末这场是 LeetCode 第 101 场双周赛,整体有点难度,第 3 题似乎比第 4 题还难一些。 2605. 从两个数字数组里生成最

    2023年04月09日
    浏览(33)
  • Leetcode 第 108 场双周赛 Problem C 将字符串分割为最少的美丽子字符串(动态规划)

    Leetcode 第 108 场双周赛 Problem C 将字符串分割为最少的美丽子字符串(动态规划) 题目 给你一个二进制字符串 s ,你需要将字符串分割成一个或者多个 子字符串 ,使每个子字符串都是 美丽 的。 如果一个字符串满足以下条件,我们称它是 美丽 的: 它不包含前导 0 。 它是

    2024年02月15日
    浏览(33)
  • Leetcode周赛 | 2023-7-23

    01背包啊。01背包啊!怎么能一直往回溯上想!还是对动态规划太不熟悉了!这不就是01背包吗?还要别人提示才知道。 哈希,用双指针应该也可以。 也是动态规划啊!怎么能又想回溯!这道题如果两层遍历会超时,要保存前面遍历过的,当前点为奇数的最大值,和当前点为

    2024年02月16日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包