Description
You are given an integer n
and an undirected graph with n
nodes labeled from 0 to n - 1
and a 2D array edges
, where edges[i] = [ui, vi]
indicates an edge between nodes ui
and vi
.
You are also given a string label
of length n
, where label[i]
is the character associated with node i
.
You may start at any node and move to any adjacent node, visiting each node at most once.
Return the maximum possible length of a palindrome that can be formed by visiting a set of unique nodes along a valid path.
Β
Example 1:
Input: n = 3, edges = [[0,1],[1,2]], label = "aba"
Output: 3
Explanation:
- The longest palindromic path is from node 0 to node 2 via node 1, following the path
0 β 1 β 2
forming string"aba"
. - This is a valid palindrome of length 3.
Example 2:
Input: n = 3, edges = [[0,1],[0,2]], label = "abc"
Output: 1
Explanation:
- No path with more than one node forms a palindrome.
- The best option is any single node, giving a palindrome of length 1.
Example 3:
Input: n = 4, edges = [[0,2],[0,3],[3,1]], label = "bbac"
Output: 3
Explanation:
- The longest palindromic path is from node 0 to node 1, following the path
0 β 3 β 1
, forming string"bcb"
. - This is a valid palindrome of length 3.
Β
Constraints:
1 <= n <= 14
n - 1 <= edges.length <= n * (n - 1) / 2
edges[i] == [ui, vi]
0 <= ui, vi <= n - 1
ui != vi
label.length == n
label
consists of lowercase English letters.- There are no duplicate edges.
Solution
C++
class Solution {
public:
static const int MAXN = 14;
int memo[1 << MAXN][MAXN][MAXN];
int maxLen(int n, vector<vector<int>>& edges, string label) {
vector<vector<int>> graph(n);
for (const auto& edge : edges) {
int u = edge[0], v = edge[1];
graph[u].push_back(v);
graph[v].push_back(u);
}
for (int m = 0; m < (1 << n); ++m)
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
memo[m][i][j] = -1;
function<int(int, int, int)> dp = [&](int mask, int u, int v) -> int {
if (memo[mask][u][v] != -1) return memo[mask][u][v];
int res = 0;
for (int u2 : graph[u]) {
if (mask & (1 << u2)) continue;
for (int v2 : graph[v]) {
if (u2 == v2) continue;
if (mask & (1 << v2)) continue;
if (label[u2] != label[v2]) continue;
int newMask = mask | (1 << u2) | (1 << v2);
res = max(res, 1 + dp(newMask, u2, v2));
}
}
return memo[mask][u][v] = res;
};
int res = 1;
// odd-length centers
for (int node = 0; node < n; ++node) {
int mask = 1 << node;
res = max(res, 1 + 2 * dp(mask, node, node));
}
// even-length centers
for (const auto& edge : edges) {
int u = edge[0], v = edge[1];
if (label[u] != label[v]) continue;
int mask = (1 << u) | (1 << v);
res = max(res, 2 * (1 + dp(mask, u, v)));
}
return res;
}
};