繁体   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