首页 >资讯 > > 正文

LeetCode 周赛 346(2023/05/21)仅 68 人 AK 的最短路问题

博客园 2023-05-22 13:33:09

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


【资料图】

LeetCode 单周赛第 345 场 · 体验一题多解的算法之美单周赛 345 概览

T1. 删除子串后的字符串最小长度(Easy)

标签:栈

T2. 字典序最小回文串(Medium)

标签:贪心、双指针

T3. 求一个整数的惩罚数(Medium)

标签:回溯、状态压缩、前缀和

T4. 修改图中的边权(Hard)

标签:贪心、最短路

T1. 删除子串后的字符串最小长度(Easy)
https://leetcode.cn/problems/minimum-string-length-after-removing-substrings/
题解(栈)

使用栈模拟扫描过程,当扫描到 DB时检查栈顶元素,最后栈内剩余的元素个数就是无法消除的最小长度:

class Solution {    fun minLength(s: String): Int {        val stack = ArrayDeque()        for (c in s) {            if (c == "D" && stack.isNotEmpty() && stack.peek() == "C") stack.pop()            else if (c == "B" && stack.isNotEmpty() && stack.peek() == "A") stack.pop()            else stack.push(c)        }        return stack.size    }}

复杂度分析:

时间复杂度:$O(n)$ 其中 n 为 s 字符串的长度;空间复杂度:$O(n)$ 栈空间。T2. 字典序最小回文串(Medium)
https://leetcode.cn/problems/lexicographically-smallest-palindrome/
题解(贪心)

贪心思路:当对称位置不相等时,只需要将其中一个位置修改到与另一个位置相同时,得到的操作次数是最少的:

class Solution {    fun makeSmallestPalindrome(s: String): String {        val arr = s.toCharArray()        val n = s.length        // 判断回文串写法        for (i in 0 until n / 2) {            val j = n - 1 - i            if(arr[i] != arr[j]) {                val temp = if(arr[i] < arr[j]) arr[i] else arr[j]                arr[i] = temp                arr[j] = temp            }        }        return String(arr)    }}

复杂度分析:

时间复杂度:$O(n)$ 其中 n 为 s 字符串的长度;空间复杂度:$O(n)$ 字符数组空间。T3. 求一个整数的惩罚数(Medium)
https://leetcode.cn/problems/find-the-punishment-number-of-an-integer/
题解一(子集型回溯)

枚举每个数,使用子集型回溯检查是否存在满足条件的切分方案:

class Solution {    fun punishmentNumber(n: Int): Int {        if (n <= 3) return 1        var ret = 0        for (x in 4 .. n) {            val target = x * x            if (backTrack("$target", 0, x)) ret += target        }        return ret + 1 /* 1 满足条件 */    }    // 子集型回溯    private fun backTrack(str : String, i : Int, target : Int) : Boolean {        if (i == str.length) return target == 0        var cur = 0        for (to in i until str.length) {            cur = cur * 10 + (str[to] - "0")            if (backTrack(str, to + 1, target - cur)) return true        }        return false    }}

复杂度分析:

时间复杂度:$O(n^2)$ 每个数字 i 转字符串后的长度为 $log_i$,而枚举长度为 $log_i$ 的字符串的切分方案后 $2^{log_i}$ = i 种方案,因此整体的时间复杂度是 $O(n^2)$;空间复杂度:$O(lgn)$ 递归栈空间。题解二(状态压缩)

由于数字的长度小于 32,我们可以用 int 表示所有切分方案,再检查是否存在满足条件的切分方案:

class Solution {    fun punishmentNumber(n: Int): Int {        if (n <= 3) return 1        var ret = 0        for (x in 4 .. n) {            val target = x * x            if (check("$target", x)) ret += target        }        return ret + 1 /* 1 满足条件 */    }    // 状态压缩    private fun check(str : String, target : Int) : Boolean {        val m = str.length        val upper = (1 shl m) - 1        for (k in 1 .. upper) {            var last = 0            var sum = 0            for (i in 0 until m) {                val cur = str[i] - "0"                if (k and (1 shl i) != 0) {                    // 拆                    sum += last                    last = cur                } else{                    // 不拆                    last = last * 10 + cur                }            }            if (sum + last == target) return true        }        return false    }}

复杂度分析:

时间复杂度:同上;空间复杂度:$O(1)$ 仅使用常量级别空间。题解三(预处理 + 前缀和)

题解一和题解二在多个测试用例间会重复计算相同数字的切分方案,我们可以预处理 1 - 1000 中所有满足条件的数平方,并维护前缀和数组:

class Solution {    companion object {        private val U = 1000        private val preSum = IntArray(U + 1)        init {            for (x in 4 .. U) {                val target = x * x                if (check("$target", x)) preSum[x] += target                preSum[x] += preSum[x - 1]            }        }        // 状态压缩        private fun check(str : String, target : Int) : Boolean {        }    }    fun punishmentNumber(n: Int): Int {        return preSum[n] + 1    }}

复杂度分析:

时间复杂度:$O(U^2)$ 其中 U 是数据大小上界;空间复杂度:$O(U)$ 前缀和数组空间。T4. 修改图中的边权(Hard)
https://leetcode.cn/problems/modify-graph-edge-weights/submissions/434224996/

LeetCode 少有的难题,排进历史 Top 10 没问题吧?

问题无解的情况:

1、假设将所有负权边设置为 INF(2*10^9)时的最短路长度 dis < target(不论是否经过负权边),由于无法继续增大边权来增大最短路长度,因此问题无解;2、假设将所有负权边设置为 1 时的最短路长度 dis > target(不论是否经过负权边),由于继续增大边权最短路不可能变小,因此问题无解。

错误的思路:

先把所有负权边设置为 1,再跑 Dijkstra 最短路,如果最短路长度 dis < target,那么将其中一条负权边继续增大 “target - dis”,就能是该路径的长度恰好为 target。然而,由于增加权重后最短路长度有可能变化,所以这个思路不能保证正确性。

正确的思路:

1、先把所有负权边改为 1 跑 Dijkstra 最短路,计算出起点到终点的最短路长度。同时,如果该长度 dis > target,则问题无解;如果该长度 dis == target,则直接返回;如果该长度 dis < target,则需要补全。2、问题的关键在于,按什么顺序修改,以及修改到什么值。顺序:利用 Dijkstra 最短路算法每次使用「确定集」中最短路长度最短的节点去松弛其他点的时机,由于修改该点不会影响已确定路径,因此这是一个不错的时机;修改到什么值:需要满足 dis[0][x] + w + dis[y][e] = target,那么有 w = target - dis[0][x] - (dis[0][e] - dis[0][y]) = delta - dis[0][x] + dis[0][y]3、虽然修改后最短路不一定经过 w,但由于不断的使用最短路长度最短的节点,因此最终总能修改成功,除非修改后最短路依然小于 target(例如存在直接从 s 到 e 的边)4、最后,将未修改的边增加到 INF。
class Solution {    private val INF = 1e9.toInt()    fun modifiedGraphEdges(n: Int, edges: Array, source: Int, destination: Int, target: Int): Array {        if (source !in 0 .. n - 1 || destination !in 0 .. n - 1) return edges        if (source == destination || edges.isNullOrEmpty()) return edges        // 建图(领接表,节点号 + 边号方便修改边权)        val graph = Array(n) { ArrayList() }        for ((i, edge) in edges.withIndex()) {            graph[edge[0]].add(intArrayOf(edge[1], i))            graph[edge[1]].add(intArrayOf(edge[0], i))        }        // 第一轮最短路        val originDis = dijkstra1(graph, edges, source, destination)        if (originDis[destination] > target) return emptyArray() // 无解        // 第二轮最短路        val delta = target - originDis[destination] // 需要补全的最短路        val dis = dijkstra2(graph, edges, source, destination, delta, originDis)        if (dis[destination] < target) return emptyArray() // 无解        // 修改剩余边        for (edge in edges) {            if (edge[2] == -1) edge[2] = INF        }        return edges    }    // return:将 -1 视为 1,并计算从起点到终点的最短路    private fun dijkstra1(graph:Array>, edges: Array, source :Int, destination:Int) : IntArray {        val n = graph.size        val visit = BooleanArray(n)        val dis = IntArray(n) { INF }        dis[source] = 0        while (true) {            // 寻找最短路长度最短的节点            var x = -1            for (i in 0 until n) {                if (visit[i]) continue                if (-1 == x || dis[i] < dis[x]) x = i            }            if (x == destination) break            visit[x] = true // 标记            // 松弛相邻边            for (to in graph[x]) {                var w = edges[to[1]][2]                if (-1 == w) w = 1 // 视为 1                if (dis[x] + w < dis[to[0]]) dis[to[0]] = dis[x] + w            }        }        return dis    }    // 补全    private fun dijkstra2(graph:Array>, edges: Array, source :Int, destination:Int, delta: Int, originDis:IntArray /* 首轮计算的最短路 */) : IntArray {        val n = graph.size        val visit = BooleanArray(n)        val dis = IntArray(n) { INF }        dis[source] = 0        while (true) {            // 寻找最短路长度最短的节点            var x = -1            for (i in 0 until n) {                if (visit[i]) continue                if (-1 == x || dis[i] < dis[x]) x = i            }            if (x == destination) break            visit[x] = true // 标记            // 松弛相邻边            for (to in graph[x]) {                var w = edges[to[1]][2]                if (-1 == w) {                    // 补全(两次 Dijkstra 只修改这里)                    w = Math.max(delta - dis[x] + originDis[to[0]], 1) // 题目要求至少修改到 1                    if (w >= 1) edges[to[1]][2] = w                }                if (dis[x] + w < dis[to[0]]) dis[to[0]] = dis[x] + w            }        }        return dis    }}

复杂度分析:

时间复杂度:$O(n^2)$ 两轮最短路算法;空间复杂度:$O(m)$ 图空间。往期回顾LeetCode 单周赛第 345 场 · 体验一题多解的算法之美LeetCode 单周赛第 344 场 · 手写递归函数的通用套路LeetCode 双周赛第 104 场 · 流水的动态规划,铁打的结构化思考LeetCode 双周赛第 103 场 · 区间求和的树状数组经典应用
上一篇:当前头条:北京最新养老格局:99%老年人在家养老,机构养老不到1% 下一篇:最后一页
x
推荐阅读

LeetCode 周赛 346(2023/05/21)仅 68 人 AK 的最短路问题

2023-05-22

当前头条:北京最新养老格局:99%老年人在家养老,机构养老不到1%

2023-05-22

世界播报:艾迪普发布新一代国产化“3D引擎+工具+平台”

2023-05-22

00后新人闪耀世乒赛,林诗栋林高远连创历史,将搅乱国乒男双格局

2023-05-22

中信金属(601061):5月22日技术指标出现观望信号-“黑三兵” 要闻速递

2023-05-22

虎牙直播怎么取关一个主播 虎牙怎么解除主播

2023-05-22

发布未来三年人才工作行动方案,浦开集团不断塑造发展新动能新优势

2023-05-22

全球最资讯丨连变四条车道致追尾 车主质疑:我是前车 凭什么我全责?

2023-05-22

资讯推荐:创业板影视动漫概念股有哪几家?(5/19)

2023-05-22

焦点快报!【我家的节气故事】小满:杨梅酸爽昌乡味

2023-05-22

23只股票型ETF获资金大幅流入 三类主题基金受追捧_世界热文

2023-05-22

2023年5月21日,三原市民有话说-天天最资讯

2023-05-22

重庆银行04月21日被沪股通减持26.84万股|天天热资讯

2023-05-22

红霉素软膏,在眼部涂两下,身体会有什么变化?建议来了解下 热消息

2023-05-22

今日快看!艾比湖湿地自然保护区开展打击违法盗挖野生植物专项行动

2023-05-21

郑州最新限号2021年9月_郑州限号2021最新通知9月份

2023-05-21

当前聚焦:建行信用卡网上注销

2023-05-21

墨西哥小伙见中国快递自取货架,直呼不可思议

2023-05-21

长飞光纤: 长飞光纤光缆股份有限公司关于参加2023年投资者网上集体接待日活动的公告

2023-05-21

轻纺城收到浙商银行现金股息5823.89万元_最新资讯

2023-05-21

A股:连续14个一字跌停板!股民:出都出不来! 天天微资讯

2023-05-21

刘昊然周冬雨戛纳同框,相视而笑,男方被工作人员紧急拉走避嫌

2023-05-21

Ps2017cc中文破解版-天天讯息

2023-05-21

韩国专家团赴日考察福岛核污水处理工作|天天热门

2023-05-21

今日报丨新乡市气象台发布大风蓝色预警【Ⅳ级/一般】【2023-05-21】

2023-05-21

全球首台氢电混合动力人工智能运输机器人下线:载重65吨可自动驾驶 最资讯

2023-05-21

坠亡男生30笔房产权证全在嫌犯家中 一气合成?太快了点!

2023-05-21

岚图的AB面|环球即时

2023-05-21

34岁网红“三千哥”因喝酒去世!生前被封最狠PK,轻松喝四斤白酒-世界快资讯

2023-05-21

荣耀Magic6:曲面屏5500mAh

2023-05-21

全球短讯!鲁滨逊的简介内容_鲁滨逊的简介

2023-05-21

二本大学专业排名理科_二本大学专业 环球今热点

2023-05-21

派瑞股份董秘回复:公司在特大功率电控、光控晶闸管的基础上,不断加大研发投入

2023-05-20

清单计算规则2013(清单计算规则和定额计算规则的区别)|当前聚焦

2023-05-20

全球时讯:64.99-74.99万元 全新Jeep大切诺基4xe正式上市

2023-05-20

“残疾人也能活出精彩人生”——善满家园里的希望与梦想

2023-05-20

造梦西游3修改大师豪华版打不开_造梦西游3修改大师豪华版v3 0 9 7

2023-05-20

复古外观,首载全新第四代e:PHEV插混,新一代本田雅阁上市

2023-05-20

42.79万起,新款奥迪A6现在是否值得推荐?_全球实时

2023-05-20

焦点速递!农业社会化服务助力农业强国建设

2023-05-20

异辛醇/辛醇商品报价动态(2023-05-20) 全球热推荐

2023-05-20

新资讯:翠苑二区突发火情,现场浓烟滚滚。最新核实:火势已扑灭,暂无人员伤亡

2023-05-20

天天滚动:硬货币

2023-05-20

一“陆”知音常伴 “知音号”迎来6岁生日 快讯

2023-05-20

中国船舶七一二所签订台州大陈岛岛际交通新能源客船供货合同

2023-05-20

遗嘱怎么写才能有法律效力 全球时讯

2023-05-20

全球热点!【津云镜头】《十年绽放 津门画卷》之安居乐业

2023-05-20

热资讯!首艘国产大型邮轮定名“爱达·魔都号”,今年底将开启以上海为母港的国际航线

2023-05-20

内娱四大沉默情侣风波

2023-05-20

​外媒:特斯拉在新一轮谈判中没有承诺在印度建厂制造汽车|天天快看

2023-05-20

全球快讯:alpha通道最主要用途_alpha通道

2023-05-20

油卡圈存怎么操作_圈存的钱怎么冲微信_全球热点评

2023-05-19

格力手机核心团队解散!官网已打不开,董明珠曾称:不比苹果差,分分钟灭掉小米……

2023-05-19

携手西华大学文新学院 四川金熊猫新媒体有限公司助力产教融合_环球新消息

2023-05-19

10天破300万!2023年度“沪惠保”投保火热

2023-05-19

天天观焦点:穹顶球带吊装成功 田湾核电7号机组全面转入安装阶段

2023-05-19

C7H16的所有同分异构体的结构简式 _命名 所有哦 谢谢 世界播报

2023-05-19

天津4月新房成交价分布图

2023-05-19

【中国式现代化长三角实践】马鞍山:合作共建快“马”加鞭 世界热门

2023-05-19

北京市2023年5月19日17时00分发布沙尘蓝色预警信号

2023-05-19

国民教育毕业生是指哪些人_国民教育毕业生是什么意思

2023-05-19

花儿乐队发布最新单曲《我们》 不舍往日时光发现感动瞬间

2023-05-19

教育学类专业课程思政教学研讨会在桂林召开 全球时快讯

2023-05-19

中国旅游日|笔端有山海,中文里自然万象的风雅别称_世界今亮点

2023-05-19

环球新消息丨吐鲁番市高昌区教育考察团来汨罗考察交流

2023-05-19

​ChatGPT上线苹果版App可语音输入 后续将推出安卓版

2023-05-19

中国援马里太阳能示范村项目通过竣工验收

2023-05-19

今日看点:全球独角兽企业500强跨越速运集团牵手高德,企业用车费用再降11%

2023-05-19

佩莱格里尼:罗马不缺少牺牲精神 穆帅给我们带来很多

2023-05-19

环球快看:证券业首家!证监会批复银河证券上线数字人民币投资场外理财产品

2023-05-19

518国际博物馆日:西藏牦牛博物馆获赠金丝野牦牛等珍贵野生动物标本-每日热闻

2023-05-19

天天观速讯丨郑州市杨金路街道开展正规瓶装液化气钢瓶置换宣传

2023-05-19

永州市2023年粮食业务培训暨粮食应急和消防演练现场会在宁远举行-视点

2023-05-19

腾讯Q1营收增长11%,中通快递净利润大增-环球快看点

2023-05-19

每日快看:五五开?欧联杯最新夺冠赔率:罗马、塞维利亚均为1.90

2023-05-19

微创机器人-B(02252.HK):5月18日南向资金减持17.05万股 环球热讯

2023-05-19

【环球时快讯】56岁江珊在《后浪》状态太真实,表演接地气,贤妻良母典范

2023-05-19

英雄萨姆3ign_英雄萨姆3 最终boss攻略及注意事项-今日观点

2023-05-19

湖南职教硬核力量|长沙民政职院搭建“楚怡”产教融合创新平台结硕果

2023-05-19

LEC解说Caedrel更推:一波巨激烈的团战 T1简直太强了!-全球今头条

2023-05-18

环球时讯:帮助青年人才筑梦追梦圆梦,“梦创集市”系列活动启动

2023-05-18

家长注意!这类APP,赶紧删除!

2023-05-18

观天下!36E咪神黄婧灵新照现巨型斜“波”,网民:感受到地心吸力

2023-05-18

当前观察:山西农大和信息学院的领导科与工程

2023-05-18

美丽乡村行!衡阳交警进村开展交通安全宣讲活动

2023-05-18

环球微速讯:[路演]天力锂能:随着在建募投项目陆续试产或投产 将助力业绩增长

2023-05-18

常山北明:我们会认真考虑将AI技术应用于纺织的可行性_环球最资讯

2023-05-18

房价走势观察| 广州房价迎来"三连涨“ ,超11万套新房库存去化需18.6个月_环球短讯

2023-05-18

沪指冲高回落涨0.4% 人工智能板块掀涨停潮

2023-05-18

江西织牢水产制品保护网

2023-05-18

湖人赢G2概率仅28%:马龙直言无惧八村防约基奇 追梦支招阿彪先发-全球时快讯

2023-05-18

每日视讯:新能源高端装备制造概念上市公司股票有哪些?新能源高端装备制造股票一览

2023-05-18

横向滚屏《离火长明》6月7日发售 登陆全平台

2023-05-18

日本连续21个月出现贸易逆差_世界球精选

2023-05-18

中国学者研究阐明:交通型空气污染给呼吸系统带来多种伤害

2023-05-18

快讯 | 4月服装、鞋帽和针纺织品类零售额同比增长32.4%至1051亿元 世界快报

2023-05-18

京能置业20亿元私募债券项目更新至“已反馈”

2023-05-18

祥明智能:5月17日融资买入2154.33万元,融资融券余额2997.75万元

2023-05-18

磁悬浮汽车原理图_磁悬浮汽车原理

2023-05-18

对标世界银行新规则,打造营商环境优选地丨优化营商环境杨浦在行动④ 环球播报

2023-05-18