# Shortest Path using Meet In The Middle

• Difficulty Level : Hard
• Last Updated : 14 Sep, 2022

Given a permutation P = p1, p2, …., pn of first n natural numbers (1 ≤ n ≤ 10). One can swap any two consecutive elements pi and pi + 1 (1 ≤ i < n). The task is to find the minimum number of swaps to change P to another permutation P’ = p’1, p’2, …., p’n.

Examples:

Input: P = “213”, P’ = “321”
Output: 2
213 <-> 231 <-> 321 Input: P = “1234”, P’ = “4123”
Output: 3

Approach: This problem can be solved using Dijkstra’s Shortest Path Algorithm. Seem like there is nothing related to a graph in the statement. But assume one permutation is one vertex, then every swap of a permutation’s elements is an edge which connects this vertex with another vertex. So finding the minimum number of swaps now becomes a simple BFS/shortest path problem.
Now let’s analyze time complexity. We have n! vertices, each vertex has n – 1 adjacent vertices. We also have to store vertices visited state by map because their representations are hard to be stored by normal arrays. So total time complexity is O(N log(N!) * N!). Meet In The Middle technique can be used to make the solution faster.

Meet In The Middle solution is similar to Dijkstra’s solution with some modifications.

• Let P be the start vertex and P’ be the finish Vertex.
• Let both start and finish be roots. We start BFS from both the roots, start and finish at the same time but using only one queue.
• Push start and finish into queue’s back, visitedstart = visitedfinish = true.
• Let srcu be the root of vertex u in BFS progression. So, srcstart = start and srcfinish = finish.
• Let Du be the shortest distance from vertex u to it’s tree’s root. So Dstart = Dfinish = 0.
• While queue is not empty, pop queue’s front which is vertex u then push all vertices v which are adjacent with u and haven’t been visited yet (visitedv = false) into queue’s back, then let Dv = Du + 1, srcv = srcu and visitedv = true. Especially, if v was visited and srcv != srcu then we can immediately return Du + Dv + 1.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach``#include ``using` `namespace` `std;` `// Function to find minimum number of``// swaps to make another permutation``int` `ShortestPath(``int` `n, string start, string finish)``{``    ``unordered_map visited;``    ``unordered_map D;``    ``unordered_map src;` `    ``visited[start] = visited[finish] = ``true``;``    ``D[start] = D[finish] = 0;``    ``src[start] = start;``    ``src[finish] = finish;` `    ``queue q;``    ``q.push(start);``    ``q.push(finish);` `    ``while` `(!q.empty()) {` `        ``// Take top vertex of the queue``        ``string u = q.front();``        ``q.pop();` `        ``// Generate n - 1 of it's permutations``        ``for` `(``int` `i = 1; i < n; i++) {` `            ``// Generate next permutation``            ``string v = u;``            ``swap(v[i], v[i - 1]);` `            ``// If v is not visited``            ``if` `(!visited[v]) {` `                ``// Set it visited``                ``visited[v] = ``true``;` `                ``// Make root of u and root of v equal``                ``src[v] = src[u];` `                ``// Increment it's distance by 1``                ``D[v] = D[u] + 1;` `                ``// Push this vertex into queue``                ``q.push(v);``            ``}` `            ``// If it is already visited``            ``// and roots are different``            ``// then answer is found``            ``else` `if` `(src[u] != src[v])``                ``return` `D[u] + D[v] + 1;``        ``}``    ``}``}` `// Driver code``int` `main()``{``    ``string p1 = ``"1234"``, p2 = ``"4123"``;``    ``int` `n = p1.length();``    ``cout << ShortestPath(n, p1, p2);` `    ``return` `0;``}`

## Java

 `// Java implementation of the approach``import` `java.util.*;`` ` `class` `GFG{``     ` `// Function to find minimum number of``// swaps to make another permutation``static` `int` `ShortestPath(``int` `n, String start,``                               ``String finish)``{``    ``HashMap visited = ``new` `HashMap();``    ``HashMap D = ``new` `HashMap();``    ``HashMap src = ``new` `HashMap();``     ` `    ``visited.put(start, ``true``);``    ``visited.put(finish, ``true``);``     ` `    ``D.put(start, ``0``);``    ``D.put(finish, ``0``);``     ` `    ``src.put(start, start);``    ``src.put(finish, finish);``    ``Queue q = ``new` `LinkedList<>();``    ``q.add(start);``    ``q.add(finish);`` ` `    ``while` `(q.size() != ``0``)``    ``{``        ` `        ``// Take top vertex of the queue``        ``String u = (String)q.peek();``        ``q.remove();`` ` `        ``// Generate n - 1 of it's permutations``        ``for``(``int` `i = ``1``; i < n; i++)``        ``{``            ` `            ``// Generate next permutation``            ``StringBuilder tmp = ``new` `StringBuilder(u);``            ``char` `t = tmp.charAt(i);``            ``tmp.setCharAt(i, tmp.charAt(i - ``1``));``            ``tmp.setCharAt(i - ``1``, t);``             ` `            ``String v = tmp.toString();``             ` `            ``// If v is not visited``            ``if` `(!visited.getOrDefault(v, ``false``))``            ``{``                ` `                ``// Set it visited``                ``visited.put(v, ``true``);`` ` `                ``// Make root of u and root of v equal``                ``src.put(v, src.get(u));`` ` `                ``// Increment it's distance by 1``                ``D.put(v, D.get(u) + ``1``);`` ` `                ``// Push this vertex into queue``                ``q.add(v);``            ``}`` ` `            ``// If it is already visited``            ``// and roots are different``            ``// then answer is found``            ``else` `if` `(src.get(u) != src.get(v))``                ``return` `D.get(u) + D.get(v) + ``1``;``        ``}``    ``}``    ``return` `0``;``}``     ` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``String p1 = ``"1234"``, p2 = ``"4123"``;``    ``int` `n = p1.length();``     ` `    ``System.out.println(ShortestPath(n, p1, p2));``}``}` `// This code is contributed by pratham76`

## Python3

 `# Python3 implementation of the approach``from` `collections ``import` `deque, defaultdict` `# Function to find minimum number of``# swaps to make another permutation``def` `shortestPath(n: ``int``, start: ``str``, finish: ``str``) ``-``> ``int``:``    ``visited, D, src ``=` `defaultdict(``lambda``: ``False``), defaultdict(``        ``lambda``: ``0``), defaultdict(``lambda``: '')``    ``visited[start] ``=` `visited[finish] ``=` `True``    ``D[start] ``=` `D[finish] ``=` `0``    ``src[start], src[finish] ``=` `start, finish` `    ``q ``=` `deque()``    ``q.append(start)``    ``q.append(finish)` `    ``while` `q:` `        ``# Take top vertex of the queue``        ``u ``=` `q[``0``]``        ``q.popleft()` `        ``# Generate n - 1 of it's permutations``        ``for` `i ``in` `range``(n):``            ``v ``=` `list``(u)``            ``v[i], v[i ``-` `1``] ``=` `v[i ``-` `1``], v[i]` `            ``v ``=` `''.join(v)` `            ``if` `not` `visited[v]:``                ` `                ``# Set it visited``                ``visited[v] ``=` `True` `                ``# Make root of u and root of v equal``                ``src[v] ``=` `src[u]` `                ``# Increment it's distance by 1``                ``D[v] ``=` `D[u] ``+` `1` `                ``# Push this vertex into queue``                ``q.append(v)` `            ``# If it is already visited``            ``# and roots are different``            ``# then answer is found``            ``elif` `u ``in` `src ``and` `src[u] !``=` `src[v]:``                ``return` `D[u] ``+` `D[v] ``+` `1` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``p1 ``=` `"1234"``    ``p2 ``=` `"4123"``    ``n ``=` `len``(p1)``    ``print``(shortestPath(n, p1, p2))` `# This code is contributed by``# sanjeev2552`

## C#

 `// C# implementation of the approach``using` `System;``using` `System.Collections;``using` `System.Text;``using` `System.Collections.Generic;` `class` `GFG{``    ` `// Function to find minimum number of``// swaps to make another permutation``static` `int` `ShortestPath(``int` `n, ``string` `start,``                               ``string` `finish)``{``    ``Dictionary<``string``,``               ``bool``> visited = ``new` `Dictionary<``string``,``                                              ``bool``>();``    ``Dictionary<``string``,``               ``int``> D = ``new` `Dictionary<``string``,``                                       ``int``>();``    ``Dictionary<``string``,``               ``string``> src = ``new` `Dictionary<``string``,``                                            ``string``>();``    ` `    ``visited[start] = ``true``;``    ``visited[finish] = ``true``;``    ` `    ``D[start] = 0;``    ``D[finish] = 0;``    ` `    ``src[start] = start;``    ``src[finish] = finish;` `    ``Queue q = ``new` `Queue();``    ``q.Enqueue(start);``    ``q.Enqueue(finish);` `    ``while` `(q.Count != 0)``    ``{``        ` `        ``// Take top vertex of the queue``        ``string` `u = (``string``)q.Peek();``        ``q.Dequeue();` `        ``// Generate n - 1 of it's permutations``        ``for``(``int` `i = 1; i < n; i++)``        ``{``            ` `            ``// Generate next permutation``            ``StringBuilder tmp = ``new` `StringBuilder(u);``            ``char` `t = tmp[i];``            ``tmp[i] = tmp[i - 1];``            ``tmp[i - 1] = t;``            ` `            ``string` `v = tmp.ToString();``            ` `            ``// If v is not visited``            ``if` `(!visited.GetValueOrDefault(v, ``false``))``            ``{``                ` `                ``// Set it visited``                ``visited[v] = ``true``;` `                ``// Make root of u and root of v equal``                ``src[v] = src[u];` `                ``// Increment it's distance by 1``                ``D[v] = D[u] + 1;` `                ``// Push this vertex into queue``                ``q.Enqueue(v);``            ``}` `            ``// If it is already visited``            ``// and roots are different``            ``// then answer is found``            ``else` `if` `(src[u] != src[v])``                ``return` `D[u] + D[v] + 1;``        ``}``    ``}``    ``return` `0;``}``    ` `// Driver Code``public` `static` `void` `Main(``string``[] args)``{``    ``string` `p1 = ``"1234"``, p2 = ``"4123"``;``    ``int` `n = p1.Length;``    ` `    ``Console.Write(ShortestPath(n, p1, p2));``}``}` `// This code is contributed by rutvik_56`

Output

`3`

My Personal Notes arrow_drop_up