Java實(shí)現(xiàn)滑動(dòng)窗口算法的示例代碼
1、簡(jiǎn)述
滑動(dòng)窗口算法是一種高效解決子數(shù)組、子字符串問(wèn)題的算法,廣泛應(yīng)用于數(shù)據(jù)流處理、網(wǎng)絡(luò)限流和字符串操作等場(chǎng)景。本文將詳細(xì)解析滑動(dòng)窗口算法的核心思想、常見(jiàn)問(wèn)題及其實(shí)現(xiàn)方式,并結(jié)合具體示例和實(shí)際應(yīng)用場(chǎng)景進(jìn)行說(shuō)明。
2、核心思想
滑動(dòng)窗口是一種雙指針技術(shù),維護(hù)一個(gè)能夠在數(shù)據(jù)結(jié)構(gòu)上"滑動(dòng)"的窗口(通常由兩個(gè)指針表示)。通過(guò)動(dòng)態(tài)調(diào)整窗口的范圍,優(yōu)化計(jì)算的時(shí)間復(fù)雜度。
基本步驟:
- 初始化兩個(gè)指針
left和right,分別表示窗口的左邊界和右邊界。 - 移動(dòng)
right指針擴(kuò)大窗口,直到窗口滿足問(wèn)題的條件。 - 在滿足條件時(shí),移動(dòng)
left指針縮小窗口,尋找更優(yōu)解或移除不必要的元素。 - 重復(fù)上述過(guò)程,直到
right遍歷完整個(gè)數(shù)據(jù)結(jié)構(gòu)。

3、實(shí)踐樣例
以下是幾個(gè)經(jīng)典問(wèn)題的滑動(dòng)窗口解法:
3.1 找到字符串中所有不重復(fù)字符的最長(zhǎng)子串
給定一個(gè)字符串,找出其中不含重復(fù)字符的最長(zhǎng)子串。
import java.util.HashSet;
public class LongestSubstringWithoutRepeatingChars {
public int lengthOfLongestSubstring(String s) {
int left = 0, right = 0, maxLength = 0;
HashSet<Character> window = new HashSet<>();
while (right < s.length()) {
char c = s.charAt(right);
if (!window.contains(c)) {
window.add(c);
maxLength = Math.max(maxLength, right - left + 1);
right++;
} else {
window.remove(s.charAt(left));
left++;
}
}
return maxLength;
}
public static void main(String[] args) {
LongestSubstringWithoutRepeatingChars solution = new LongestSubstringWithoutRepeatingChars();
System.out.println(solution.lengthOfLongestSubstring("abcabcbb")); // Output: 3
}
}
3.2 滑動(dòng)窗口最大值
給定一個(gè)數(shù)組 nums 和一個(gè)大小為 k 的窗口,找到每個(gè)滑動(dòng)窗口中的最大值。
import java.util.ArrayDeque;
import java.util.Deque;
public class SlidingWindowMaximum {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length == 0) return new int[0];
int n = nums.length;
int[] result = new int[n - k + 1];
Deque<Integer> deque = new ArrayDeque<>();
for (int i = 0; i < nums.length; i++) {
// 移除窗口左側(cè)已過(guò)期的元素
if (!deque.isEmpty() && deque.peekFirst() < i - k + 1) {
deque.pollFirst();
}
// 移除所有比當(dāng)前元素小的元素,因?yàn)樗鼈儾粫?huì)成為最大值
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.pollLast();
}
deque.offerLast(i);
// 當(dāng)窗口達(dá)到大小 k 時(shí),記錄最大值
if (i >= k - 1) {
result[i - k + 1] = nums[deque.peekFirst()];
}
}
return result;
}
public static void main(String[] args) {
SlidingWindowMaximum solution = new SlidingWindowMaximum();
int[] result = solution.maxSlidingWindow(new int[]{1,3,-1,-3,5,3,6,7}, 3);
for (int r : result) {
System.out.print(r + " ");
}
// Output: 3 3 5 5 6 7
}
}
4、應(yīng)用場(chǎng)景
滑動(dòng)窗口算法因其高效性,在以下場(chǎng)景中應(yīng)用廣泛:
字符串處理:
查找字符串中的子串問(wèn)題,例如最長(zhǎng)無(wú)重復(fù)子串、包含所有指定字符的最短子串。數(shù)據(jù)流處理:
在處理實(shí)時(shí)數(shù)據(jù)流時(shí),通過(guò)滑動(dòng)窗口維護(hù)最近的狀態(tài),例如計(jì)算實(shí)時(shí)統(tǒng)計(jì)信息(平均值、最大值等)。網(wǎng)絡(luò)限流:
滑動(dòng)窗口用于實(shí)現(xiàn)動(dòng)態(tài)限流算法,限制一段時(shí)間內(nèi)的請(qǐng)求數(shù)量。數(shù)組處理:
處理固定窗口大小的問(wèn)題,例如滑動(dòng)窗口最大值、最小值等。
5、總結(jié)
滑動(dòng)窗口算法通過(guò)動(dòng)態(tài)調(diào)整窗口范圍,極大地提高了求解某些問(wèn)題的效率。在實(shí)際開(kāi)發(fā)中,可以結(jié)合問(wèn)題的特點(diǎn)靈活使用滑動(dòng)窗口 技術(shù)解決各種復(fù)雜問(wèn)題。如果你還沒(méi)有在項(xiàng)目中嘗試滑動(dòng)窗口算法,那么不妨以本文提供的代碼示例為起點(diǎn),嘗試將其應(yīng)用到實(shí)際場(chǎng)景中。
以上就是Java實(shí)現(xiàn)滑動(dòng)窗口算法的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Java滑動(dòng)窗口算法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
CommandLineRunner最佳實(shí)踐小結(jié)
CommandLineRunner是Spring Boot框架提供的一個(gè)功能接口,用于Spring Boot應(yīng)用啟動(dòng)完成后立即執(zhí)行特定的代碼邏輯,允許開(kāi)發(fā)者在應(yīng)用程序完全啟動(dòng)并準(zhǔn)備好接收請(qǐng)求之前執(zhí)行一些初始化任務(wù),下面通過(guò)實(shí)例代碼講解什么是CommandLineRunner以及CommandLineRunner用法,一起看看吧2025-08-08
Java數(shù)據(jù)類型之引用數(shù)據(jù)類型解讀
這篇文章主要介紹了Java數(shù)據(jù)類型之引用數(shù)據(jù)類型,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
spring boot整合log4j2及MQ消費(fèi)處理系統(tǒng)日志示例
這篇文章主要為大家介紹了spring boot整合log4j2及MQ消費(fèi)處理系統(tǒng)日志的示例過(guò)程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
Java Swing JTextArea文本區(qū)域的實(shí)現(xiàn)示例
這篇文章主要介紹了Java Swing JTextArea文本區(qū)域的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
SpringBoot中使用@Async實(shí)現(xiàn)異步任務(wù)調(diào)用詳解
這篇文章主要介紹了SpringBoot中使用@Async實(shí)現(xiàn)異步任務(wù)調(diào)用詳解,一個(gè)可以無(wú)需等待被調(diào)用函數(shù)的返回值就讓操作繼續(xù)進(jìn)行的方法(來(lái)自百度百科),即程序在順序執(zhí)行時(shí),不等待異步調(diào)用的語(yǔ)句返回結(jié)果就執(zhí)行后面的程序,需要的朋友可以參考下2023-12-12

