leetcode 841:钥匙和房间

Posted 枫叶艾辰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 841:钥匙和房间相关的知识,希望对你有一定的参考价值。

import java.util.*;

/**
 * @Class CanVisitAllRooms
 * @Description 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 的房间。
 * <p>
 * 最初,除 0 号房间外的其余所有房间都被锁住。
 * 你可以自由地在房间之间来回走动。
 * 如果能进入每个房间返回 true,否则返回 false。
 * <p>
 * 示例 1:
 * 输入: [[1],[2],[3],[]]
 * 输出: true
 * 解释:
 * 我们从 0 号房间开始,拿到钥匙 1。
 * 之后我们去 1 号房间,拿到钥匙 2。
 * 然后我们去 2 号房间,拿到钥匙 3。
 * 最后我们去了 3 号房间。
 * 由于我们能够进入每个房间,我们返回 true。
 * <p>
 * 示例 2:
 * 输入:[[1,3],[3,0,1],[2],[0]]
 * 输出:false
 * 解释:我们不能进入 2 号房间。
 * <p>
 * 提示:
 * 1 <= rooms.length <= 1000
 * 0 <= rooms[i].length <= 1000
 * 所有房间中的钥匙数量总计不超过 3000。
 * @Author
 * @Date 2020/6/24
 **/
public class CanVisitAllRooms {
}
/**
 * 解法1:bfs利用队列实现
 */
public static boolean canVisitAllRooms(List<List<Integer>> rooms) {
	if (rooms.size() == 0) {
		return true;
	}
	Map<Integer, Boolean> map = new HashMap<>();
	for (int i = 0; i < rooms.size(); i++) {
		map.put(i, false);
	}

	Queue<Integer> integerQueue = new LinkedList<>();
	// 0号房间全部入队列
	for (int i = 0; i < rooms.get(0).size(); i++) {
		((LinkedList<Integer>) integerQueue).push(rooms.get(0).get(i));
	}

	while (integerQueue.size() > 0) {
		int i = ((LinkedList<Integer>) integerQueue).pop();
        // 表示i号房间已进入过
		if (map.get(i).booleanValue() == true) continue;       

		int size = rooms.get(i).size();

		for (int j = 0; j < size; j++) {
			int temp = rooms.get(i).get(j);
            // 判断temp号房间是否已加入队列
			if (integerQueue.contains(temp)) continue;         
			((LinkedList<Integer>) integerQueue).push(temp);
		}

		map.put(i, true);//标记进入i房间号
	}

	for (int i = 1; i < map.size(); i++) {
		if (map.get(i).booleanValue() == false) {
			return false;
		}
	}
	return true;
}
/**
 *  解法2:利用set和栈,set的特征就是不重复,使用栈实现dfs
 */
public static boolean canVisitAllRooms(List<List<Integer>> rooms) {
	if(rooms==null || rooms.isEmpty()){
		return true;
	}

	Set<Integer> visited =new HashSet<>();
	Deque<List<Integer>> listDeque = new LinkedList<>();
	listDeque.add(rooms.get(0));
	visited.add(0);
	while (!listDeque.isEmpty()){
		for (Integer integer : listDeque.poll()){
			if(visited.add(integer)) listDeque.add(rooms.get(integer));
		}
	}

	return visited.size() == rooms.size();
}
// 测试用例
public static void main(String[] args) {
	List<List<Integer>> rooms = new ArrayList<>();
	for (int i = 1; i <= 3; i++) {
		List<Integer> list = new ArrayList<>();
		list.add(i);
		rooms.add(list);
	}

	List<Integer> list = new ArrayList<>();
	rooms.add(list);
	boolean ans = canVisitAllRooms(rooms);
	System.out.println("demo01 result:" + ans);

	rooms.clear();
//        [[1,3],[3,0,1],[2],[0]]
	List<Integer> integerList01 = new ArrayList<>();
	integerList01.add(1);
	integerList01.add(3);
	rooms.add(integerList01);

	List<Integer> integerList02 = new ArrayList<>();
	integerList02.add(3);
	integerList02.add(0);
	integerList02.add(1);
	rooms.add(integerList02);

	List<Integer> integerList03 = new ArrayList<>();
	integerList03.add(2);
	rooms.add(integerList03);

	List<Integer> integerList04 = new ArrayList<>();
	integerList04.add(0);
	rooms.add(integerList04);

	ans = canVisitAllRooms(rooms);
	System.out.println("demo02 result:" + ans);

	// 特殊情况:[[]]
	rooms.clear();
	rooms.add(new ArrayList<>());
	ans = canVisitAllRooms(rooms);
	System.out.println("demo03 result:" + ans);


//        [[],[1,1],[2,2]]
	rooms.clear();
	List<Integer> integerList41 = new ArrayList<>();
	rooms.add(integerList41);

	List<Integer> integerList42 = new ArrayList<>();
	integerList42.add(1);
	integerList42.add(1);
	rooms.add(integerList42);

	List<Integer> integerList43 = new ArrayList<>();
	integerList43.add(2);
	integerList43.add(2);
	rooms.add(integerList43);
	ans = canVisitAllRooms(rooms);
	System.out.println("demo04 result:" + ans);

//        [[2,3],[],[2],[1,3,1]]
	rooms.clear();
	List<Integer> integerList51 = new ArrayList<>();
	integerList51.add(2);
	integerList51.add(3);
	rooms.add(integerList51);

	List<Integer> integerList52 = new ArrayList<>();
	rooms.add(integerList52);

	List<Integer> integerList53 = new ArrayList<>();
	integerList53.add(2);
	rooms.add(integerList53);

	List<Integer> integerList54 = new ArrayList<>();
	integerList54.add(1);
	integerList54.add(3);
	integerList54.add(1);
	rooms.add(integerList54);
	ans = canVisitAllRooms(rooms);
	System.out.println("demo05 result:" + ans);
}

以上是关于leetcode 841:钥匙和房间的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 841:钥匙和房间 Keys and Rooms

BFS广度优先搜索之钥匙和房间

LeetCode刷题笔记-数据结构-day19

LeetCode刷题笔记-数据结构-day19

LeetCode刷题笔记-数据结构-day19

数据结构与算法之深入解析“钥匙和房间”的求解思路与算法示例