【leetcode】718 最長重複子數組(滑動窗口解法)

前言

  • 這是今日的每日一題,但是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
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章