來看哈我們這道例題
我們第一種想法應該就是暴力求解,枚舉每個子數組
當我們枚舉第一個數的時候,我們要從第一個數開始挨個枚舉每個結尾
如圖,以第一個數開頭的最長不重復數我們就枚舉完了
然后我們讓兩個指針全部到第二個數
再枚舉第二個數能到達的最長子數組
如圖還是到這就停止了,我們再枚舉第三個數
依舊是到這里停止,我們其實啊,沒必要非得每次枚舉都退回去,我們可以讓l++,直到達到合法的區間之后,再繼續往后枚舉長度
也就是說?當我們到這個狀態的時候,別讓r退回去了,我們讓左指針不斷加加,直到達到一個合法的區間之后,再讓r往后走
這道題,就算我們想用暴力枚舉,我們也用不了的
因為暴力枚舉時間復雜度是N平方,我們會超時的
而滑動窗口時間復雜度只是O(N),我們最差的情況就算l和r把數組都掃描了一遍,此時時間復雜度是N+N? 也就是O(N)
我們再來捋一遍我們滑動窗口的步驟
step1:初始化,l=1 r=1 unordered map<int,int> mp;
step2:進窗口,r指針指向的元素在哈希表++
step3:判斷是否為合法區間 即mp[a[r]]<=1→如果不合法就step5:出窗口 也就是不斷讓mp[a[l]]-- l++,直到mp[a[r]]<=1
step6:已經是合法區間了,我們更新長度
#include <iostream>
#include <unordered_map>
using namespace std;
const int N = 1e6+10;
int a[N];
int n;
int main()
{int T;cin >> T;while(T--){cin >> n;for(int i = 1;i<=n;i++){cin >> a[i];}unordered_map <int,int> mp;int l = 1,r = 1;int ret = 0;while(r<=n){mp[a[r]]++;//進窗口 while(mp[a[r]]>1)//判斷 {mp[a[l]]--;//出窗口 l++;}ret = max(ret,r-l+1);//更新結果 r++;}cout << ret << endl;}return 0;
}