時間:20180906
題目描述 :
LeetCode 841. Keys and Rooms
有 N 個房間,開始時你位于 0 号房間。每個房間有不同的号碼:0,1,2,...,N-1,并且房間裡可能有一些鑰匙能使你進入下一個房間。
在形式上,對于每個房間 i 都有一個鑰匙清單 rooms[i],每個鑰匙 rooms[i][j] 由 [0,1,...,N-1] 中的一個整數表示, 其中 N = rooms.length。 鑰匙 rooms[i][j] = v 可以打開編号為 v 的房間。
最初,除 0 号房間外的其餘所有房間都被鎖住。你可以自由地在房間之間來回走動。如果能進入每個房間傳回 true,否則傳回 false。要求先寫出解題思路,再編寫代碼。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1TVU9UNFpHW4R2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TM3YzMxUzM5AzNwkDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
通過廣度優先搜尋(BFS)的方式進行探索。将可通路的0房間加入隊列之中,通路隊列中的一個元素,周遊他可以到達的房間,如果該房間還不能被通路,那麼設定為通路,否則跳過。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Stack;
public class KeysAndRooms {
public static void main(String[] args) {
//[[1],[2],[3],[]]
List<List<Integer>> rooms = new ArrayList();
List<Integer> keys0 = new ArrayList<>();
keys0.add(1);
List<Integer> keys1 = new ArrayList<>();
keys1.add(2);
List<Integer> keys2 = new ArrayList<>();
keys2.add(3);
List<Integer> keys3 = new ArrayList<>();
rooms.add(keys0);
rooms.add(keys1);
rooms.add(keys2);
rooms.add(keys3);
System.out.println(canVisitAllRooms(rooms));
}
private static boolean canVisitAllRooms(List<List<Integer>> rooms) {
//用棧存儲下一步要參觀的房間
Stack<Integer> dfs = new Stack<>();
dfs.add(0);
//用hashset存儲已經參觀過的房間
HashSet<Integer> seen = new HashSet<Integer>();
seen.add(0);
while (!dfs.isEmpty()) {
int i = dfs.pop();
for (int j : rooms.get(i))
if (!seen.contains(j)) {
dfs.add(j);
seen.add(j);
if (rooms.size() == seen.size()) return true;
}
}
return rooms.size() == seen.size();
}
}