leetcode.841 鑰匙和房間

有 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

示例 1:

輸入: [[1],[2],[3],[]]
輸出: true
解釋:  
我們從 0 號房間開始,拿到鑰匙 1。
之後我們去 1 號房間,拿到鑰匙 2。
然後我們去 2 號房間,拿到鑰匙 3。
最後我們去了 3 號房間。
由於我們能夠進入每個房間,我們返回 true。

示例 2:

輸入:[[1,3],[3,0,1],[2],[0]]
輸出:false
解釋:我們不能進入 2 號房間。

提示:

  1. 1 <= rooms.length <= 1000
  2. 0 <= rooms[i].length <= 1000
  3. 所有房間中的鑰匙數量總計不超過 3000

思路:使用 bfs 的思路,用 set 記錄是否訪問過了,進入每一個房間並將其房間鑰匙表入隊和進 set,set 的作用是避免重複訪問和最後輸出結果。

代碼:

class Solution {
    public boolean canVisitAllRooms(List<List<Integer>> rooms) {
        // 判空
        if(rooms.size() == 0 || rooms == null) throw new IllegalArgumentException();
        int N = rooms.size();    // 取得房間數
        Set<Integer> set = new HashSet<>();
        set.add(0);     
        Queue<Integer> queue = new LinkedList<>();
        List<Integer> room = rooms.get(0);
        for(int i = 0;i < room.size() ; ++i){
            queue.offer(room.get(i));
            set.add(room.get(i));
        }
        while(!queue.isEmpty()){
            int m = queue.poll();
            set.add(m);
            room = rooms.get(m);
            for(int i = 0;i < room.size() ; ++i){
                if(!set.add(room.get(i))) continue;  // 避免重複訪問
                queue.offer(room.get(i));     // 將鑰匙表入隊
            }
        }
        for(int j = 0;j < N;++j){
            // 看看是否有未進入的房間
            if(!set.contains(j)) return false;   
        }
        return true;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章