Longest Common Substring
Problem
Two words are given. Print the length of the longest continuous part that appears in both words. (A substring is continuous, unlike a subsequence.) If they share no letter, print 0.
Constraints
- 1 <= length <= 1000
- lowercase letters
Examples
Input
abcdxyz xyzabcd
Output
4
Solutions
If a[i] equals b[j], the common part that ends here is one longer than the common part that ended at (i - 1, j - 1). If they differ, it is 0. The best value seen is the answer. O(n m) time, O(m) memory.
/*
* Problem : Longest common part.
* Input : Two words.
* Output : The length.
* Approach: DP with one row
* Time : O(n m)
* Space : O(m)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static int solve(String a, String b) {
// Step 1: run[j] is the length of the common ending of a[0..i] and b[0..j-1]. One row is enough.
int[] run = new int[b.length() + 1];
int best = 0;
for (int i = 1; i <= a.length(); i++) {
// Step 2: Go from right to left, so run[j - 1] still holds the value of the previous row.
for (int j = b.length(); j >= 1; j--) {
if (a.charAt(i - 1) == b.charAt(j - 1)) {
run[j] = run[j - 1] + 1;
best = Math.max(best, run[j]);
} else {
// Step 3: A different letter breaks the common part.
run[j] = 0;
}
}
}
return best;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String a = scanner.next();
String b = scanner.next();
System.out.println(solve(a, b));
}
}
Hints (2)
- Why does a mismatch give 0?
- Why go from right to left?