【Swift】LeetCode 3. 无重复的最长子串
3. 无重复的最长子串
题目描述
思路 and Swift 题解
这道题目可谓是面试题中经典中的经典,在 CodeTop 上的排名断档式地排在了第一位。我曾在今年五月的一次面试当中遇到了这个题目。解决这道题目的思路其实不难,考察的就是我们对“滑动窗口”这个知识点的掌握。
首先,我们建立一个字典,并建立双指针slow
和fast
,从左向右对这个字符串进行遍历。fast
在遍历的每次循环当中固定向右移动一个位置,并将遇到的字符加入到字典当中作为 Key,使用 Value 作为字符的出现次数。与此同时,当fast
所在位置的字符在字典中出现的次数超过1
次时,就需要开始维护滑动窗口,不断地将slow
位置(初始为第一个位置,也就是下标索引0
)的字符从字典当中删除一次,并对slow
进行右移,直到fast
所在位置的字符出现的次数不超过1
为止。此时,slow
和fast
之间的区间就是无重复的子串,每次使用一个变量来记录最大的长度,最后将其返回即可得到答案。
在使用 Swift 进行解题时,需要注意几个点:
- 字符串不能够直接通过下标进行访问,如果建立的字典类型是
[Character: Int]
,那么就需要先显式地将字符串String
通过Array()
构造器转为数组(这个数组的类型是[Character]
,再进行操作); - Swift 在通过 Key 对 Dictionary 进行访问时,得到的 Value 都是可选类型的。因此如果要对 Value 的值进行修改,需要使用
map[Key]!
,也就是加上!
来解除可选类型。这样做只有在我们确定可选类型有值时才是安全的,如果不能确定可选类型是否有值,应该使用可选绑定或default
。如果 Key 不存在于 Dict 当中,但使用Dict[Key]!
,那么将会导致运行时错误。
完整的 Swift 题解是:
class Solution {func lengthOfLongestSubstring(_ s: String) -> Int {var chars = Array(s) // String 转为 [Character]var mp = [Character: Int]()var slow = 0, fast = 0, ans = 0while fast < chars.count {mp[chars[fast], default: 0] += 1while mp[chars[fast], default: 0] > 1 {mp[chars[slow]]! -= 1slow += 1}ans = max(ans, fast - slow + 1)fast += 1}return ans}
}