[英]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.