📜  使用中间会议的最短路径

📅  最后修改于: 2021-06-27 02:03:56             🧑  作者: Mango

给定一个置换P = p 1 ,p 2 ,…,。 n个前n个自然数(1≤n≤10) 。可以交换任意两个连续元素p ip i + 1 (1≤i 。的任务是找到交换到变化P的最小数量的另一排列P“= P” 1,P“2,…,第” N。

例子:

方法:可以使用Dijkstra的最短路径算法解决此问题。似乎语句中没有与图相关的内容。但是假设一个排列是一个顶点,那么排列元素的每次交换都是一条边,该边将该顶点与另一个顶点连接起来。因此,现在找到最小数量的交换成为一个简单的BFS /最短路径问题。
现在让我们分析时间复杂度。我们有n!顶点,每个顶点有n – 1个相邻顶点。我们还必须存储通过地图访问过的顶点,因为它们的表示很难被普通数组存储。因此,总时间复杂度为O(N log(N!)* N!) 。中间相遇技术可用于加快解决方案的速度。
中间相遇解决方案与Dijkstra的解决方案类似,但有一些修改。

  • P为起始顶点, P’为结束顶点。
  • 让起点和终点都扎根。我们从两个根目录开始BFS,同时开始和结束,但仅使用一个队列。
  • 将start和finish推入队列的后部, visited start = Visited finish = true
  • src u为BFS进程中顶点u的根。因此, src start = start和src finish = finish
  • D u为顶点u到树的根的最短距离。因此D start = D finish = 0
  • 当队列不为空时,弹出队列的前部(顶点为u),然后将与u相邻但尚未被访问(访问过v = false)的所有顶点v推入队列的后部,然后让D v = D u + 1src v = src u并且访问过v = true 。特别是,如果v被访问并且src v != src u,那么我们可以立即返回D u + D v + 1

下面是上述方法的实现:

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 visited = new Dictionary();
    Dictionary D = new Dictionary();
    Dictionary src = new Dictionary();
     
    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


输出:
3

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。