滑動視窗的核心就是,右指標給視窗擴容,直至抵達擴容限制條件或抵達邊界;左指標則是給視窗縮容,以釋放限制條件的約束,保證視窗繼續向邊界移動。
需求講解
給定一個字串 str ,請找出其中不含有重複字元的最長子串的長度。
public static int lengthOfLongestSubstring(String str) {
// 記錄視窗內字元
Set<Character> set = new HashSet<>();
int max = 0; // 最長不重複字元子串的長度
int left = 0, right = 0; // 滑動視窗的左右邊界
while (right < str.length()) {
char c = str.charAt(right);
// 如果字元在視窗內出現過,則滑動左邊界
while (set.contains(c)) {
set.remove(str.charAt(left));
left++;
}
// 將字元加入視窗
set.add(c);
// 更新最大長度
max = Math.max(max, right - left + 1);
// 右邊界右移
right++;
}
return max;
}
此演算法通常應用此類場景:在大區間,尋找(滿足某種特徵的)小區間結果。比如:
陣列中的最大/最小子序列問題
例如,“最大連續子陣列和”,“最小覆蓋子串”等。這些問題通常需要找出陣列或字串中的一段連續子區間,使其滿足某種條件(如和最大或最小,或者包含所有指定字元等)。
計數類問題
例如,“和為K的子陣列個數”,“所有字母異位詞”等。這類問題需要統計滿足特定條件的子陣列或子字串的數量。
字串匹配問題
例如,“KMP演算法”,“Boyer-Moore演算法”等。這類問題需要在字串中找到指定模式的所有出現位置。
其他
滑動視窗演算法還可以用於解決一些其他問題,例如:
- 尋找最長公共子串
- 尋找最長上升子序列
- 尋找最長迴文子串
- 計算滑動平均值
滑動視窗演算法的優點在於,它可以將這些看似複雜的問題轉化為線性複雜度,大大提高了演算法的執行效率。
以下是一些具體的應用案例:
-
在網路協議中,滑動視窗演算法可以用於流量控制和擁塞控制。
-
在資料庫中,滑動視窗演算法可以用於查詢最佳化。
-
在機器學習中,滑動視窗演算法可以用於特徵提取。