【Swift】LeetCode 76. 最小覆盖子串

76. 最小覆盖子串

题目描述

思路 and Swift 题解

这道题目是一道比较复杂的滑动窗口题目。

解决这道题目的思路是,针对st,开两个 Dictionary,类型是[Character: Int],分别记录s子串当中出现过字符的数量以及字符串t当中字符出现过的数量,命名为msmt。然后,针对字符串s,维护一个从左到右子串的滑动窗口,在窗口当中比较mt当中出现过的字符的数量是否小于等于ms当中相应字符出现过的数量(以mt的 Key 作为ms的 Key,比较二者 Value 的大小)。如果满足mt当中出现过的字符都在当前ms字典当中,且ms当中字符出现过的数量≥\geq≥mt当中字符出现过的数量,就说明当前的窗口满足条件,设置startminLen来记录当前窗口的起始点与长度。

再然后,我们就需要对窗口进行缩小,也就是调整左边界。如果以上条件持续满足,那么取左边界的字符,将其出现过的次数从ms当中删除一次。如果仍然满足,则持续上述行为,并相应调整startminLen;如果不满足,则继续向右滑动窗口,寻找下一次可能的答案。

最后,如果ms当中的一个窗口满足了题意,那么返回这个窗口对应的子串;否则返回空字符串。可以设置初始时var minLen = s.count + 1,如果滑动窗口维护结束时minLen仍然是s.count + 1,就说明s当中没有满足题意的子串,返回空字符串。

上面的思路是没问题的,但存在的一个问题就是,每一次维护滑动窗口左边界时,都需要完全比对一次msmt两个字典,时间复杂度非常高。一个优化的思路是,我们不在每次维护左边界时比对两个字典,而是维护一个名为valid的整型变量,它的初始值为0,作用就是记录当前滑动窗口当中多少个在p当中出现过的字符的数量与在滑动窗口当中出现的相应字符的数量相同。如果valid == mt.count,就说明当前的滑动窗口满足题意,开始对左边界进行维护。维护左边界left时,需要相应地调整valid的值,如果ms[s[left]] == mt[s[left]],由于此时需要将s[left]从滑动窗口当中删除,导致ms[s[left]] != mt[s[left]],因此需要valid -= 1

完整的 Swift 题解:

swift 复制代码
class Solution {
    func minWindow(_ s: String, _ t: String) -> String {
        guard !s.isEmpty && !t.isEmpty else {
            return ""
        }

        var s = Array(s), t = Array(t)
        var ms = [Character: Int](), mt = [Character: Int]()

        for i in 0..<t.count {
            mt[t[i], default: 0] += 1
        }

        var left = 0, right = 0, valid = 0, start = 0, minLen = s.count + 1
        while right < s.count {
            var c = s[right]
            right += 1

            if mt[c] != nil {
                ms[c, default: 0] += 1
                if ms[c] == mt[c] {
                    valid += 1
                }
            }

            while valid == mt.count {
                // 如果已经 t 当中字符出现的数量已经与 s 的子串当中相应字符出现的数量相同, 就开始收缩左边界
                var currLen = right - left
                if currLen < minLen {
                    start = left
                    minLen = currLen
                }

                var d = s[left]
                left += 1

                if mt[d] != nil {
                    if ms[d] == mt[d] {
                        valid -= 1
                    }
                    ms[d]! -= 1
                }
            }
        }
        
        return minLen == s.count + 1 ? "" : String(s[start..<(start + minLen)])
    }
}
相关推荐
初级代码游戏2 小时前
iOS开发 SwitftUI 13:提示、弹窗、上下文菜单
ios·swiftui·swift·弹窗·消息框
zhyongrui5 小时前
托盘删除手势与引导体验修复:滚动冲突、画布消失动画、气泡边框
ios·性能优化·swiftui·swift
zhangfeng11338 小时前
CSDN星图 支持大模型微调 trl axolotl Unsloth 趋动云 LLaMA-Factory Unsloth ms-swift 模型训练
服务器·人工智能·swift
zhyongrui1 天前
SnipTrip 发热优化实战:从 60Hz 到 30Hz 的性能之旅
ios·swiftui·swift
大熊猫侯佩2 天前
Neo-Cupertino 档案:撕开 Actor 的伪装,回归 Non-Sendable 的暴力美学
swift·observable·actor·concurrency·sendable·nonsendable·data race
2501_915921433 天前
在没有源码的前提下,怎么对 Swift 做混淆,IPA 混淆
android·开发语言·ios·小程序·uni-app·iphone·swift
00后程序员张4 天前
对比 Ipa Guard 与 Swift Shield 在 iOS 应用安全处理中的使用差异
android·开发语言·ios·小程序·uni-app·iphone·swift
大熊猫侯佩4 天前
星际穿越:SwiftUI 如何让 ForEach 遍历异构数据(Heterogeneous)集合
swiftui·swift·遍历·foreach·any·异构集合·heterogeneous
hjs_deeplearning4 天前
认知篇#15:ms-swift微调中gradient_accumulation_steps和warmup_ratio等参数的意义与设置
开发语言·人工智能·机器学习·swift·vlm
墨瑾轩5 天前
C# PictureBox:5个技巧,从“普通控件“到“图像大师“的蜕变!
开发语言·c#·swift