原文題目
Given a string s
, find the length of the longest substring without repeating characters.
題目摘要
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.
解題思路
left
和 right
分別控制滑動窗口的左右邊界,right
用來遍歷字串,left
用來調整窗口大小以保證窗口內不包含重複字符。Set<Character>
來儲存當前窗口中的字符,這個集合用來快速檢查當前窗口內是否有重複字符。right
進行遍歷,每次將 right
指向的字符加入到 Set
中。Set
中已經存在 right
指向的字符,說明當前窗口內有重複字符。left
指標來縮小窗口,並且移除 left
指向的字符,直到窗口內不再包含重複字符。right - left + 1
),並更新 maxLength
,保留最大值。right
遍歷到字串末尾後,返回 maxLength
作為最長的不重複子字串的長度。程式碼
class Solution {
public int lengthOfLongestSubstring(String s) {
Set<Character> charSet = new HashSet<>(); //用來儲存當前不重複的字符集合
int maxLength = 0; //紀錄最長的不重複子字串長度
int left = 0; //設立左指標來控制滑動窗口的左邊界
//右指標遍歷整個字串
for (int right = 0; right < s.length(); right++) {
//當字符集合中包含當前右指標指向的字符時
while (charSet.contains(s.charAt(right))) {
charSet.remove(s.charAt(left)); //移除左指標指向的字符
left++; //左指標右移,縮小窗口
}
charSet.add(s.charAt(right)); //將當前右指標指向的字符加入集合
maxLength = Math.max(maxLength, right - left + 1); //更新最長子字串的長度
}
return maxLength; //回傳最長的不重複子字串長度
}
}
結論
這道題目是用滑動視窗來解決,在解題過程中,滑動窗口的左右指標可以有效地幫助我們動態地調整範圍,確保窗口內的字元不重複。同時透過 Set 來快速檢查重複字元,讓我們能夠在遇到重複字元時,及時調整左指標 來縮小窗口,並不斷更新最長子字串的長度。透過這次練習,能更好地理解如何在大數據或長字串的情況下,利用滑動窗口技術來解決重複元素檢查的問題。