The O(n) Club: Maximum Length of Repeated Subarray — Why Subsequence Logic Will Betray You
⚡ TL;DR
Want the length of the longest common chunk in two integer arrays—no skips allowed? Don’t let your LCS muscle memory sabotage you. Brute force would involve checking every pair (unless you’re trying to start a fire with your CPU). Use this bottom-up DP instead:
// Java: DP for repeated subarray int maxLen = 0; int[][] dp = new int[m+1][n+1]; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (A[i-1] == B[j-1]) { dp[i][j] = dp[i-1][j-1] + 1; maxLen = Math.max(maxLen, dp[i][j]); } } }
🧠 How Devs Usually Mess This Up
Raise your hand if you’ve ever pasted your Longest Common Subsequence code here without reading the fine print—now go put that hand in the ice bucket. Subarrays are contiguous; subsequence logic, which takes wild hops and skips, will give you a result that only makes sense after six coffees and some denial. Don’t be That Dev.
🔍 What’s Actually Going On
Imagine you’re lining up two cassette tapes and looking for the longest bit where the music is identical and continuous — no record scratches, no fast-forwarding. The only thing that helps? A DP table. Each cell says, “How long is the current matching run if arrays A and B match at these indexes?” If the numbers match, you extend the run; if not, the counter resets faster than your willpower during Friday deployments. It’s classic Longest Common Substring… except it’s numbers, not strings, and you still shouldn’t use your LCS code.
🛠️ PseudoCode
- Set up your DP grid: Make a 2D array
dp[m+1][n+1]
filled with zeroes. No, not for Sudoku practice—just trust me. - Walk through both arrays: For each (i, j), check if
A[i-1] == B[j-1]
. - If they match:
dp[i][j] = dp[i-1][j-1] + 1
. This extends your current streak of matching numbers. - If not:
dp[i][j] = 0
. Game over for this cell—move on. - Track your best run: Keep updating
maxLen
ifdp[i][j]
beats your previous best. - Result: Get
maxLen
at the end. Enjoy the feeling of not being haunted by off-by-one errors (for once).
💻 The Code
// Java - Dynamic Programming Solution
public int findLength(int[] A, int[] B) {
int m = A.length, n = B.length;
int[][] dp = new int[m+1][n+1];
int maxLen = 0;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (A[i-1] == B[j-1]) {
dp[i][j] = dp[i-1][j-1] + 1;
maxLen = Math.max(maxLen, dp[i][j]);
} // else dp[i][j] stays 0
}
}
return maxLen;
}
Pro tip: If your interviewer’s memory budget is stricter than your gym trainer, you can compress this to a 1D array (but don’t try it the first time after two hours of sleep).
⚠️ Pitfalls, Traps & Runtime Smacks
- Subarray ≠ Subsequence — 80% of rejected submissions are just this fundamental mix-up. Don’t be the meme.
- Indexing carnage: All those +1 shifts and
i-1
vsi
combos. Double-check, triple-caffeine. - Memory spikes: If
A.length
andB.length
approach 1000, be aware your DP matrix just ate a million cells. 1D DP is your friend for interviews and RAM emergencies. - Alternative ways to overthink: Rolling hash/binary search is neat, but you’ll spend more time debugging it than explaining it to your grandma.
🧠 Interviewer Brain-Tattoo
“LCS logic here is like using a butter knife for brain surgery. If you see ‘subarray’, don’t reach for your old subsequence hacks!”