Shortest Path using Meet In The Middle

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:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to find minimum number of
// swaps to make another permutation
int ShortestPath(int n, string start, string finish)
{
    unordered_map<string, bool> visited;
    unordered_map<string, int> D;
    unordered_map<string, string> src;
  
    visited[start] = visited[finish] = true;
    D[start] = D[finish] = 0;
    src[start] = start;
    src[finish] = finish;
  
    queue<string> 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;
}

chevron_right


Output:

3


My Personal Notes arrow_drop_up

pawanasipugmailcom

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.