给定的3个字符的起始字符串X,精加工的3个字符的字符串Y和禁止字符串数组。任务是找到从X达到Y的最小点击次数。
规则:
- 3个字符中的每个字符都以循环方式更改,即,每次单击时,您都可以从a到b或a到z,并且从未显示禁止字。
- 如果无法达到Y ,则打印-1 。每次单击只能更改一个字母。
- 每个禁止的字符串具有以下形式:{ “ S1”“ S2”“ S3”}其中每个字符串S i包含该字符的禁止字母。
- 禁止的字符串= {“ ac”,“ bx”,“ lw”}表示禁止使用单词“ abl”,“ cxw”,“ cbl”,“ abw”,“ cbw”,“ axl”,“ axw”和“ cxl”,并且将永远不会显示。
注意:如果起始字符串X也是可能的禁止字符组合,则结果也应该为-1。
Input: X = “znw”, Y = “lof”, N = 4 (no of forbidden strings)
forbidden =
{ ” qlb “, ” jcm “, ” mhoq ” },
{ ” azn “, ” piy “, ” vj ” },
{ ” by “, ” oy “, ” ubo ” },
{ ” jqm “, ” f “, ” ej ” }
Output: Minimum no of clicks required is 22
Explanation: Since no combination out of the given forbidden strings forms the final string Y, so the string Y becomes valid.Thus minimum number of clicks required is computed as:
z – l in forward direction by 12 clicks
z – l in backward direction by 14 clicks
n – o in forward direction by 1 click
n – o in backward direction by 25 clicks
w – f in forward direction by 9 clicks
w – f in backward direction by 17 clicksTotal minimum clicks = 12 + 1 + 9 = 22.
Input: X = “bdb”, Y = “xxx”, N = 1 (no of forbidden strings)
forbidden = { ” ax “, ” acx “, ” bxy ” }
Output: Minimum no of clicks required is -1
Explanation: As “xxx” is a possible combination of forbidden characters, therefore it is not possible to reach Y from X.方法:
使用BFS(广度优先搜索)进行某些修改,以绕过禁止的字符串以获得最小的点击次数。
- 由于这3个位置中的每个位置都可以包含字母,因此,为了遍历单词状态,请创建尺寸为26 * 26 * 26的3D访问数组。
- 要可视化每个受限制的单词,请创建另一个尺寸为26 * 26 * 26的3D数组,以跟踪在遍历中绝不能访问的单词。
- 由于3个字符中的每个字符都以循环方式更改,即,每次单击时字母将以循环方式更改,因此,每次到达下一个字母时,都需要注意对26取模。
- 令单词的当前状态为[XYZ] 。然后,只需单击一下,便可以移动到以下6个状态:
[ X+1 Y Z ], [ X-1 Y Z ], [ X Y+1 Z ], [ X Y-1 Z ], [ X Y Z+1 ], [ X Y Z-1 ].
- 因此,创建3个实用程序数组dx,dy,dz,以使遍历过程简化。将每个单词状态存储在一个结构中,该结构具有4个字段,即a,b,c(三个字符的每个)和距起始单词的距离。
下面是上述方法的实现:
C++
// C++ code for above program. #include
using namespace std; #define int long long int // each node represents a word state struct node { int a, b, c; // dist from starting word X int dist; }; // 3D visited array bool visited[26][26][26]; // 3D restricted array bool restricted[26][26][26]; // utility arrays for single step // traversal in left and right int dx[6] = { 1, -1, 0, 0, 0, 0 }; int dy[6] = { 0, 0, 1, -1, 0, 0 }; int dz[6] = { 0, 0, 0, 0, 1, -1 }; // function to find the // minimum clicks. void solve(string start, string end, int qx, const vector >& forbidden) { memset(visited, 0, sizeof(visited)); memset(restricted, 0, sizeof(restricted)); for (auto vec : forbidden) { string a = vec[0]; string b = vec[1]; string c = vec[2]; for (auto x : a) for (auto y : b) for (auto z : c) { // each invalid word is // decoded and marked as // restricted = true. restricted[x - 'a'] [y - 'a'] [z - 'a'] = true; } } // starting and ending letter a int sa = start[0] - 'a'; int ea = end[0] - 'a'; // starting and ending letter b int sb = start[1] - 'a'; int eb = end[1] - 'a'; // starting and ending letter c int sc = start[2] - 'a'; int ec = end[2] - 'a'; if (restricted[sa][sb][sc] or restricted[ea][eb][ec]) { // check if starting word // or finishing word is // restricted or not cout << -1 << endl; return; } // queue of nodes for BFS queue q; // initial starting word pushed in // queue. dist = 0 for starting word q.push({ sa, sb, sc, 0 }); // mark as visited visited[sa][sb][sc] = true; while (!q.empty()) { node x = q.front(); q.pop(); // final destination reached condition if (x.a == (end[0] - 'a') and x.b == (end[1] - 'a') and x.c == (end[2] - 'a')) { cout << x.dist << endl; return; } int DIST = x.dist; for (int i = 0; i < 6; i++) { // mod 26 for circular letter sequence // next letter for a int A = (x.a + dx[i] + 26) % 26; // next letter for b int B = (x.b + dy[i] + 26) % 26; // next letter for c int C = (x.c + dz[i] + 26) % 26; if (!restricted[A][B][C] and !visited[A][B][C]) { // if a valid word state, // push into queue q.push({ A, B, C, DIST + 1 }); visited[A][B][C] = true; } } } // reach here if not possible // to reach final word Y cout << -1 << endl; } // Driver Code signed main() { // starting string string X = "znw"; // final string string Y = "lof"; // no of restricting word vectors int N = 4; vector > forbidden = { { "qlb", "jcm", "mhoq" }, { "azn", "piy", "vj" }, { "by", "oy", "ubo" }, { "jqm", "f", "ej" } }; solve(X, Y, N, forbidden); return 0; }
输出:22
时间复杂度: O(26 * 26 * 26),因为最大时可以有26 * 26 * 26个字状态。
空间复杂度: O(26 * 26 * 26)