题目:有N个房间,一开始你在0号房间。每个房间都有不同的编号:0,1,2,...,N-1,房间里可能有一些钥匙可以让你进入下一个房间。正式来说,有一个钥匙列表rooms[i]代表每个房间i,每个关键房间[i][j]由[0,1,...,N-1]中的整数表示,其中N=房间。长度。钥匙rooms[i][j]=v可以打开编号为v的房间。最初,除了房间0之外的所有房间都被锁定。您可以在房间之间自由来回移动。如果每个房间都可以进入,则返回true,否则返回false。有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。示例1:输入:[[1],[2],[3],[]]输出:true解释:我们从房间0开始,拿到钥匙1。之后我们去房间1,拿到钥匙2。然后我们去房间2拿到钥匙3。我们最终去了房间3。因为我们能够进入每个房间,所以我们返回true。示例2:输入:[[1,3],[3,0,1],[2],[0]]输出:false解释:我们不能进入房间2。提示:1<=rooms.length<=10000<=rooms[i].length<=1000所有房间的钥匙总数不超过3000个。注意:1<=rooms.length<=10000<=rooms[i].length<=1000中的钥匙数量所有房间加起来最多3000个。解题思路:很简单的一道题,从0号房间开始递归遍历即可。唯一需要注意的是如何判断一个房间是否被访问过。您可以使用设置的哈希表来记录您访问过的房间数。最后,如果哈希表的长度等于房间的长度,则说明所有房间都是可达的。代码:集合集合(Java):classSolution{Set>rooms){helper(rooms,0);returnset.size()==rooms.size();//如果长度相等,则可以到达所有房间}privatevoidhelper(List
>rooms,intindex){if(set.contains(索引))返回;set.add(index);//将访问过的房间号添加到哈希表中for(Integeri:rooms.get(index)){//遍历房间的每个keyhelper(rooms,i);//进入递归}}}可以看出,使用哈希表求解问题,在递归期间会调用很多set函数,比如set.add()和set.contains()。与解决这个问题的时间相比,这个开销是非常大的。对于这道题,用数组完全可以避免。Java:classSolution{publicbooleancanVisitAllRooms(List
>rooms){intlen=rooms.size();int[]visited=newint[len];//初始化一个等长数组,数组的每个值默认为0helper(rooms,0,visited);for(inti:visited)if(i==0)returnfalse;//如果数组中还有0,则证明还有房间没有被访问过returntrue;}privatevoidhelper(List
>rooms,intindex,int[]visited){if(visited[index]==1)return;//如果房间已经被访问过,直接返回visited[index]=1;//在访问过的房间中,将其改为1标记为(Integeri:rooms.get(index)){//Traversehelper(rooms,i,visited);}}}Python:classSolution:defcanVisitAllRooms(self,rooms:List[List[int]])->bool:size=len(rooms)self.visited=[False]*size#初始化等长数组,默认为False,不访问所有房间self.helper(rooms,0)returnall(self.visited)defhelper(self,rooms:List[List[int]],index:int)->None:ifself.visited[index]:#如果是True、房间已经被访问过,直接返回returnself.visited[index]=True#访问过的房间标记为Trueforiinrooms[index]:#遍历keysself.helper(rooms,i)#进入递归函数欢迎关注微信。新工。公众号:爱写Bug
