题目来源:https://leetcode.com/contest/weekly-contest-111/problems/find-the-shortest-superstring/
问题描述
Given an array A of strings, find any smallest string that contains each string in A
as a substring.
We may assume that no string in A
is substring of another string in A
.
Example 1:
Input: ["alex","loves","leetcode"]
Output: "alexlovesleetcode"
Explanation: All permutations of "alex","loves","leetcode" would also be accepted.
Example 2:
Input: ["catg","ctaagt","gcta","ttca","atgcatc"]
Output: "gctaagttcatgcatc"
Note:
1 <= A.length <= 12
1 <= A[i].length <= 20
------------------------------------------------------------
题意
定义一个字符串集合S的母串sp为一个使得∀s∈S, s==substr(sp) . 给定一组字符串,已知没有任何一个字符串是另一个的子串,求这组字符串的最短母串(如有多个,给出任意一个即可)。
------------------------------------------------------------
思路
以字符串为节点,字符串之间的共同前缀后缀长度为边,建立有向图。问题转化为求有向图的最长哈密顿道路。
建图过程:对于字符串集合中的字符串a与字符串b, 如果a[-i:] == b[0:i],则从a向b连一条长度为i的有向边,表示a的后缀与b的前缀共用,b在a后;同理,如果a[0:j] == b[-j:],则从b向a连一条长度为j的有向边,表示b的后缀与a的前缀共用,a在b后。
最长哈密顿道路:回忆最短哈密顿道路的题目POJ 3311 Hie with the Pie(状压DP),我们用状态压缩动态规划求解。同样,最长哈密顿道路也可以用状压DP求解。用dp[s][i]表示经过的节点组成的状态为s的时候,到达节点i所经过的长度,其中(s & (1< 回溯:由于题目要求输出路径,所以求出最长哈密顿道路的长度之后,还要回溯找到最长哈密顿道路的各个节点的顺序,按顺序输出。采用的方法是令dp数组的元组为一个类,类属性包括道路长度和前驱节点,并置起始节点的前驱为-1,反向回溯直至遇到-1节点,可以得到逆序的路径,再逆序输出即可。 ------------------------------------------------------------ 代码 class Solution {
public:
const static int NMAX = 12;
class node {
public:
int len, pre; // len: length of Hamilton path; pre: pre string id
node(void) : len(0), pre(-1) {}
node(int len, int pre) : len(len), pre(pre) {}
};
int n;
int mat[NMAX][NMAX] = {};
node dp[1 << NMAX][NMAX];
void build_graph(vector