簡體   English   中英

重復子數組的最大長度(leetcode)

[英]Maximum Length of Repeated Subarray (leetcode)

我正在查看這個leetcode question ,並且在完成天真的方法時遇到了問題。 我能來的最佳解決方案在這里 但我不確定我天真的嘗試有什么問題。

問題如下:

給定兩個整數數組 A 和 B,返回出現在兩個數組中的子數組的最大長度。

例子:
輸入:A:[1,2,3,2,1] B:[3,2,1,4,7]

輸出:3

解釋:最大長度的重復子數組是[3, 2, 1]。

這是我當前的代碼:

var findLength = function(a, b) {
    if (a.length === 0 || b.length === 0) {
        return 0;
    }
    
    let aWithoutFinalNumber = a.slice(0, a.length - 1);
    let bWithoutFinalNumber = b.slice(0, b.length - 1);

    let aFinalNumber = a[a.length - 1];
    let bFinalNumber = b[b.length - 1];
    
    // matching numbers
    if(aFinalNumber === bFinalNumber) {
        return 1 + findLength(aWithoutFinalNumber, bWithoutFinalNumber);
    } else { // mismatch. Compete to find the maximum length.
        return Math.max(findLength(a, bWithoutFinalNumber), findLength(aWithoutFinalNumber, b));
    }
};

我的解決方案通過了幾個測試用例,但在a: [0,1,1,1,1] b: [1,0,1,0,1]a: [0,1,1,1,1] b: [1,0,1,0,1]情況下失敗了。 對我的錯誤的任何見解將不勝感激!

您可以使用嵌套循環,當兩個數組中出現相同的元素時,您可以開始增加這兩個索引,直到兩個數組中的元素相同。 為您提供最大元素集的結果將是返回的結果。

 function maxSub(a, b) { let result = null; function findAll(i, j) { const res = []; if (a[i] !== b[j] || a[i] == undefined || b[j] == undefined) { return res; } return res.concat(a[i], ...findAll(i + 1, j + 1)) } a.forEach((e, i) => { b.forEach((c, j) => { if (e == c) { const sub = findAll(i, j); if (!result || sub.length > result.length) { result = sub } } }) }) return result; } console.log(maxSub([0, 1, 1, 1, 1], [1, 0, 1, 0, 1])) console.log(maxSub([1, 2, 3, 2, 1], [3, 2, 1, 4, 7]))

問題來自您在最后一個元素匹配時計算最大長度的方式。 這是一個最小的例子:

 var findLength = function(a, b) { if (a.length === 0 || b.length === 0) { return 0; } let aWithoutFinalNumber = a.slice(0, a.length - 1); let bWithoutFinalNumber = b.slice(0, b.length - 1); let aFinalNumber = a[a.length - 1]; let bFinalNumber = b[b.length - 1]; // matching numbers if(aFinalNumber === bFinalNumber) { return 1 + findLength(aWithoutFinalNumber, bWithoutFinalNumber); //< -- problem here } else { // mismatch. Compete to find the maximum length. return Math.max(findLength(a, bWithoutFinalNumber), findLength(aWithoutFinalNumber, b)); } }; console.log(findLength([1, 0, 2, 1], [1, 0, 3, 1]));

如果有任何匹配,則將最大長度加1 ,但如果稍后出現不匹配,則不一定如此。 這是一個縮短的版本,為了更容易理解,插圖會發生什么:

[1, 0, 2, 1]
          ^-------|
[1, 0, 3, 1]      | -- match, max length +1
          ^-------|
______

[1, 0, 2, 1]
       ^----------|
[1, 0, 3, 1]      | -- mismatch, max length +0
       ^----------|

______

[1, 0, 2, 1]
    ^-------------|
[1, 0, 3, 1]      | -- match, max length +1
    ^-------------|

______

[1, 0, 2, 1]
 ^----------------|
[1, 0, 3, 1]      | -- match, max length +1
 ^----------------|

當您合計所有匹配項時,您會得到3但是,如果出現不匹配,計數應該已重置。

為了避免這個問題,可以對算法進行的一個簡單更改是將當前計數作為參數傳遞給函數。 這樣,您可以控制何時需要重置計數:

 var findLength = function(a, b, maxSoFar = 0) { //<-- default count of zero if (a.length === 0 || b.length === 0) { return maxSoFar; //<-- return the count } let aWithoutFinalNumber = a.slice(0, a.length - 1); let bWithoutFinalNumber = b.slice(0, b.length - 1); let aFinalNumber = a[a.length - 1]; let bFinalNumber = b[b.length - 1]; // matching numbers if(aFinalNumber === bFinalNumber) { const newMax = maxSoFar + 1; //<-- increment the count return Math.max(newMax, findLength(aWithoutFinalNumber, bWithoutFinalNumber, newMax)); //<-- return the newMax in case the next is a mismatch } else { // mismatch. Compete to find the maximum length. return Math.max(findLength(a, bWithoutFinalNumber), findLength(aWithoutFinalNumber, b)); //<-- reset the count } }; console.log(findLength([1, 0, 2, 1], [1, 0, 3, 1])); console.log(findLength([1, 2, 3, 2, 1], [3, 2, 1, 4, 7])); console.log(findLength([0, 1, 1, 1, 1], [1, 0, 1, 0, 1]));

您也可以將 dp 與表格一起使用。 我嘗試了其他代碼,它在以下情況下出錯:[0,0,0,0,1,0,0] 和 [0,0,0,0,0,1,0]。 這是相同的python代碼。

def findLength(a, b):
    if len(a)==0 or len(b)==0:
        return 0
        
    n=len(a)
    m=len(b)

    dp=[[0 for _ in range(n+1)] for _ in range(m+1)]
    maxSoFar=0
       
    for i in range(1,m+1):
        for j in range(1,n+1):
            if a[j-1]==b[i-1]:
                dp[i][j]=dp[i-1][j-1]+1
                maxSoFar=max(maxSoFar,dp[i][j])
            else:
                dp[i][j]=0
                    
    return maxSoFar

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM