前言
- 這是今日的每日一題,但是leetcode題解裏對滑動窗口的解法動圖之類有特別強烈的誤導性,導致一般很難寫出滑動窗口的解法。我自己研究之後,將他們錯誤的流程圖改編成正確的流程便於以後有類似需求可以想到。
原理
- 這個滑動窗口的寫法跟一般滑動窗口寫法不太一樣,一般滑動窗口只要移動指針就完事了,這個滑動窗口其實不應該看成滑動窗口,而應該去找規律。
- leetcode題解裏面對這題雖然動圖意思對的,但是順序以及注意點都有強烈誤導性,導致正常人看了動圖壓根寫不出這種循環。所以我拿別人圖將順序和過程以及注意點改造了下:
- 紅線部分作爲分界線,右邊第一列爲窗口長度,leetcode裏5窗口那裏搞個4,而且順序還是反的,並且沒有下面的4那行,極具誤導性,讓你想不到咋寫。
- 第二列就是2個數組的起始索引。
- 這個圖放出來,規律一下子就看出來了。for循環2個數組長度和,當i比數組大時,就是個分界線,窗口大小會以第二個數組爲主導。索引方面,分界線前,下面那個數組起始索引恆爲0,分界線後,上面那個數組索引恆爲0。另一部分索引分界線前倒序,分界線後正序。
- 第二個for循環就各自從起始索引開始,窗口長度結束進行對比即可。
代碼
function maxLength(A:number[], B:number[], aStart:number, bStart:number, len:number){
let max = 0, count = 0;
for (let i = 0; i < len; i++) {
if (A[aStart + i] == B[bStart + i]) {
count++;
max = Math.max(max, count);
} else {
count = 0;
}
}
return max;
}
function findLength(A: number[], B: number[]): number {
let aLength= A.length
let bLength= B.length
let ret=0
let total = aLength + bLength ;
for (let i = 0; i < total; i++) {
let aStart = 0;
let bStart = 0;
let len = 0;
if (i < aLength) {
aStart = aLength - i - 1;
bStart = 0;
len = i + 1;
} else {
aStart = 0;
bStart = i - aLength;
len = Math.min(bLength - bStart, aLength);
}
let maxlen = maxLength(A, B, aStart, bStart, len);
ret = Math.max(ret, maxlen);
}
return ret
};