WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Dynamic Programming · Advanced · question 54 of 100

Solve the problem of finding the Shortest Common Superstring of a set of strings using dynamic programming.?

📕 Buy this interview preparation book: 100 Dynamic Programming questions & answers — PDF + EPUB for $5

The problem of finding the shortest common superstring of a set of strings is a classic problem in string manipulation and can be solved using dynamic programming. The basic idea is to use a table to store the lengths of the shortest common superstrings of all possible combinations of substrings from the set of input strings. We then can reconstruct the shortest common superstring by backtracking through the table.

Here’s how to implement the solution using dynamic programming:

1. Build a graph whose vertices are the strings and the edges are the overlaps of the strings. An overlap occurs when the end of one string matches the beginning of another string.

2. Find the shortest path that visits every vertex exactly once. This is equivalent to finding the Hamiltonian path in the graph.

3. Once we have the shortest path, we can concatenate the strings in the order they appear on the path, skipping over the overlapping characters of adjacent strings.

4. If an overlapping character is found, we just keep the non-overlapping part.

5. Return the resulting superstring.

For example, let’s say we are given the input strings "ACGT", "CGTA", "GTAC", "TACG". We can build a graph with vertices "ACGT", "CGTA", "GTAC", "TACG" and edges between each pair of vertices that overlap.

  ACGT  CGTA  GTAC  TACG
  |     |     |     |
  CGTA  GTAC  ACGT  ACGT
  |     |     |     |
  GTAC  TACG  CGTA  CGTA
  |     |     |     |
  TACG  ACGT  TACG  GTAC

We can then use dynamic programming to solve this problem by creating a table of size 24x4 for all the possible combinations of the vertices and their lengths.

    ACGT  CGTA  GTAC  TACG
0000  0     0     0     0
0001  4     4     4     4
0010  4     4     4     4
0011  7     6     7     6
0100  4     4     4     4
0101  7     7     7     7
0110  7     7     7     7
0111 10     9    10     9
1000  4     4     4     4
1001  7     7     7     7
1010  7     7     7     7
1011 10    10    10    10
1100  7     7     7     7
1101 10    10    10    10
1110 10    10    10    10
1111 13    12    13    12

The cell at the bottom-right corner of the table shows the length of the shortest common superstring for all the input strings. We can then backtrack through the table to find the actual superstring by following the path with the shortest length. Using the same example, the optimal order of concatenating the strings together is "ACGTACGTA" which is the shortest common superstring for the given set of input strings.

Here’s the Java code for the solution:

public static String shortestCommonSuperstring(String[] strings) {
    int n = strings.length;
    int[][] dp = new int[1 << n][n];
    int[][] overlaps = new int[n][n];

    // Create overlaps graph
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (i != j) {
                int p = 0;
                while (p < strings[i].length() && strings[j].startsWith(strings[i].substring(p))) {
                    p++;
                }
                overlaps[i][j] = p;
            }
        }
    }

    // Populate dp table
    for (int i = 1; i < (1 << n); i++) {
        Arrays.fill(dp[i], Integer.MAX_VALUE);
        for (int j = 0; j < n; j++) {
            if ((i & (1 << j)) > 0) {
                if (i == 1 << j) {
                    dp[i][j] = strings[j].length();
                } else {
                    for (int k = 0; k < n; k++) {
                        if (k != j && (i & (1 << k)) > 0 && dp[i - (1 << j)][k] != Integer.MAX_VALUE) {
                            dp[i][j] = Math.min(dp[i][j], dp[i - (1 << j)][k] + strings[j].length() - overlaps[k][j]);
                        }
                    }
                }
            }
        }
    }

    // Trace back shortest path to reconstruct superstring
    int minIndex = 0, minVal = Integer.MAX_VALUE;
    for (int i = 0; i < n; i++) {
        if (dp[(1 << n) - 1][i] < minVal) {
            minIndex = i;
            minVal = dp[(1 << n) - 1][i];
        }
    }
    StringBuilder sb = new StringBuilder(strings[minIndex]);
    int used = 1 << minIndex;
    while (used < (1 << n)) {
        int next = -1;
        for (int i = 0; i < n; i++) {
            if ((used & (1 << i)) == 0 && dp[used][minIndex] == dp[used | (1 << i)][i] + strings[i].length() - overlaps[minIndex][i]) {
                next = i;
                break;
            }
        }
        sb.append(strings[next].substring(overlaps[minIndex][next]));
        used |= 1 << next;
        minIndex = next;
    }
    return sb.toString();
}
Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Dynamic Programming interview — then scores it.
📞 Practice Dynamic Programming — free 15 min
📕 Buy this interview preparation book: 100 Dynamic Programming questions & answers — PDF + EPUB for $5

All 100 Dynamic Programming questions · All topics