LeetCode:訪問所有節點的最短路徑【847】


LeetCode:訪問所有節點的最短路徑【847】

題目描述

給出 graph 為有 N 個節點(編號為 0, 1, 2, ..., N-1)的無向連通圖。 

graph.length = N,且只有節點 i 和 j 連通時,j != i 在列表 graph[i] 中恰好出現一次。

返回能夠訪問所有節點的最短路徑的長度。你可以在任一節點開始和停止,也可以多次重訪節點,並且可以重用邊。

示例 1:

輸入:[[1,2,3],[0],[0],[0]]
輸出:4
解釋:一個可能的路徑為 [1,0,2,0,3]

示例 2:

輸入:[[1],[0,2,4],[1,3,4],[2],[1,2]]
輸出:4
解釋:一個可能的路徑為 [0,1,4,2,3] 

提示:

  1. 1 <= graph.length <= 12
  2. 0 <= graph[i].length < graph.length

題目分析

  1.拿到這個問題時,我們先進行初步分析

    分析示例,我們可以知道每個節點是可以被重復訪問的,這樣子就出現了一個問題,很有可能程序將陷入一個死循環,不斷在某幾個節點直接無線循環下去

    為了解決這個問題,我們可以使用二進制值來保存節點的訪問狀態:

    

  2.該用什么算法來描述訪問所有節點的問題呢?

    訪問所有節點其實就是一種搜索算法,只是現在我們不是搜索每個確定的節點值,而是有條件的狀態搜索(比如目標狀態為1111)。

    題目中說,你可以在任一節點開始和停止,那每個節點都應該是搜索的一種初始狀態,並且從每個節點的這個初始狀態去探索其他狀態,並且最終找到目標狀態前,遍歷了所有的可能性,是一種典型的BFS算法應用

  3.BFS算法的過程是怎么樣的?

    我們都知道BFS搜索的算法描述是一棵樹,那么算法的第一層是每個節點,接下來每層數的擴展都算路徑中的一步(因為每一層代表了所有的可能性,在這么多可能性中至少有一種是可以最終找到目標狀態的),最后知道找到目標狀態,返回的步驟就是最短路徑。

  

  4.二進制狀態與搜索的互相作用是怎么樣的?

    我們說了每一次搜索都要參考二進制狀態,來避免死循環。每個節點都要一張所有狀態的表格,比如第一個節點的某個狀態被激活了,后來在某一次搜索中又回到第一個節點,並且狀態發現這個狀態出現過,那么很顯然,這樣走下去就會死循環,我們就可以跳過這種情況。

    這樣會出現一個情況,同一種狀態,對於不同節點來說是不一樣的,對於1號節點可能是死循環,但是對與2號節點來說很可能是正常的。

  5.節點與狀態之間的轉換是怎樣的?就是從一個節點到另一個節點,狀態是怎么變化的?

    這里我們采用了或的方式來進行狀態轉換控制,比如訪問0號節點的時候狀態是0001,接下來要訪問2號節點,那么狀態就會變為(0001 | 0100 =0101)!

Java實現

package graph;

import java.util.LinkedList;
import java.util.Queue;

public class ShortestPathLength_847 {

    public int shortestPathLength(int[][] graph) {
        int kAns = (1<<graph.length)-1;
        Queue<Pair>  q  = new LinkedList<>();
        int[][] visited = new int[graph.length][1<<graph.length];
        for(int i=0;i<graph.length;i++)
            q.offer(new Pair(i,1<<i));

        int steps =0;
        while (!q.isEmpty())
        {
            int s = q.size();
            while (s-->0)
            {
                Pair pair = q.poll();
                int n = pair.i;
                int state = pair.j;
                if(state==kAns)
                    return steps;
                if(visited[n][state]==1)
                    continue;
                visited[n][state]=1;
                for(int next:graph[n])
                    q.offer(new Pair(next,state|(1<<next)));
            }
            steps++;
        }
        return -1;
    }


class Pair{
    int i,j;

    public Pair(int i, int j) {
        this.i = i;
        this.j = j;
    }
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM