[LeetCode] 3. Longest Substring without Repeating Characters(最长的无重复字符的子串)
-
Difficulty: Medium
-
Related Topics: Hash Table, Two Pointers, String, Sliding Window.
-
Link: https://leetcode.com/problems/longest-substring-without-repeating-characters/
Description
Given a string s
, find the length of the longest substring without repeating characters.
给定一字符串 s
,返回其最长的无重复子串的长度。
Examples
Example 1
Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Example 2
Input: s = "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Example 3
Input: s = "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
Example 4
Input: s = ""
Output: 0
Constraints
0 <= s.length <= 5 * 1e4
s
consists of English letters, digits, symbols and spaces.
Solution
这种子串类的题目,用滑动窗口可以比较直观地解决。就是维护一个窗口,保证窗口内的元素不重复。具体怎么维护,参见以下代码:
import kotlin.math.max
class Solution {
fun lengthOfLongestSubstring(s: String): Int {
var result = 0
// 滑动窗口的左右边界
var left = 0
var right = 0
// 子串内字符和其下标的映射
val charIndices = hashMapOf<Char, Int>()
while (right < s.length) {
// right 向右扩展,直到遇见重复字符
while (right < s.length && !charIndices.containsKey(s[right])) {
charIndices[s[right]] = right
right++
}
// 更新结果
result = max(result, right - left)
if (right == s.length) {
break
}
// left 向右扩展,舍弃在重复字符左侧的所有字符
val dupIndex = charIndices.getValue(s[right])
while (left <= dupIndex) {
charIndices.remove(s[left])
left++
}
}
return result
}
}