841. 钥匙和房间

今天挑一个广搜的题目做一下。

其实我广搜的题熟练度一般/(ㄒoㄒ)/~~ 主要还是太久没做了……

这个题目不是很难,非常适合寻找手感……

这里先贴上别的大佬整理的知识点讲解:

知乎-算法讲解之广度优先搜索

博客园-广度优先搜索原理与实践

BFS是有套路可言的:

void bfs(起始点) {将起始点放入队列中;标记起点访问;while (如果队列不为空) {  // 一般采用while ,当然也可以使用递归访问队列中队首元素x;删除队首元素;for (x 所有相邻点) {if (该点未被访问过且合法) {将该点加入队列末尾;if  (该结点是目标状态) {  // 达到目标,提前结束终止循环置 flag= true;    break; }}}}队列为空,广搜结束;
}

对于这道题目,上面模板完全够用。不过我有点毛手毛脚,每一次提交都会发现自己还有一些特殊情况没有考虑。所以大概提交了三次,才完全覆盖所有的情况。

具体因为什么原因WA的,记不太起来了……但有一些大概的印象。大概有以下几个方面:

1、判断是否访问过每一个房间的标准有误。我记得我是通过创建visited的List集合解决的。但集合这种数据结构有一个问题:不能查重,我是通过判断visited的长度与rooms的长度是否相等

visited.size() == rooms.size()

来得出是否遍历完的结果。所以这个长度是很关键的,没有查重时,有重复的元素时就会得出错误的长度。因此,最终我换成了Set。

2、入口结点的元素没有加到邻接点集合中。我用neighborPoints来存每个结点的邻接点。但是没有把入口位置也就是0号结点的内容存进去……最后也会导致结果出错。

3、没有判断首元素(0号房间)内容为空的情况。即,0号房间中没有钥匙的情况。一上来就调用0号元素值,直接异常了。

4、在线OJ不能使用static变量。从本地拷贝过去的时候没改(因为牛客上似乎可以),结果代码一样,在线OJ结果和本地不一样。还好我疑惑的时间不是很长……

5、巩固了一些方法:

集合的addAll()方法非常方便;

neighborPoints.addAll(rooms.get(0));
neighborPoints.addAll(rooms.get(cur));  //获得cur房间的所有钥匙

Map的getOrDefault()方法也很方便,久了没用容易想不起:

status.getOrDefault(neighbor, false)

最终AC的代码如下:

class Solution {Deque<Integer> queue = new ArrayDeque<>();Set<Integer> visited = new HashSet<>();Map<Integer, Boolean> status = new HashMap<Integer, Boolean>();List<Integer> neighborPoints = new ArrayList<>();public boolean canVisitAllRooms(List<List<Integer>> rooms) {System.out.println(rooms);if(rooms.get(0).isEmpty()){return false;}int first = rooms.get(0).get(0);    //将起点放入队列neighborPoints.addAll(rooms.get(0));visited.add(0);queue.add(first);status.put(first, false);while(!queue.isEmpty()) {int cur = queue.poll();status.put(cur, true);
//            System.out.println(cur);visited.add(cur);neighborPoints.addAll(rooms.get(cur));  //获得cur房间的所有钥匙for (Integer neighbor : neighborPoints) {if(!status.getOrDefault(neighbor, false))   //  未遍历{if(queue.contains(neighbor)) {continue;}queue.add(neighbor);status.put(neighbor, false);}}}return visited.size() == rooms.size();}
}

本地的测试代码:

import java.util.*;/*** Created with IntelliJ IDEA.* Description:* User: 12569* Date: 2023-06-05* Time: 9:35*/
public class Test2 {Deque<Integer> queue = new ArrayDeque<>();static Set<Integer> visited = new HashSet<>();Map<Integer, Boolean> status = new HashMap<Integer, Boolean>();List<Integer> neighborPoints = new ArrayList<>();public boolean canVisitAllRooms(List<List<Integer>> rooms) {System.out.println(rooms);int first = rooms.get(0).get(0);    //将起点放入队列neighborPoints.addAll(rooms.get(0));visited.add(0);queue.add(first);status.put(first, false);while(!queue.isEmpty()) {int cur = queue.poll();status.put(cur, true);
//            System.out.println(cur);visited.add(cur);neighborPoints.addAll(rooms.get(cur));  //获得cur房间的所有钥匙for (Integer neighbor : neighborPoints) {if(!status.getOrDefault(neighbor, false))   //  未遍历{if(queue.contains(neighbor)) {continue;}queue.add(neighbor);status.put(neighbor, false);}}}return visited.size() == rooms.size();}public static void main(String[] args) {
//        [2,3],[],[2],[1,3]Test2 test2 = new Test2();List<Integer> r0 = new ArrayList<Integer>();r0.add(1);
//        r0.add(2);r0.add(3);List<Integer> r1 = new ArrayList<Integer>();r1.add(3);r1.add(0);r1.add(1);
//        r1.add(2);List<Integer> r2 = new ArrayList<Integer>();r2.add(2);List<Integer> r3 = new ArrayList<Integer>();
//        r3.add(1);
//        r3.add(3);r3.add(0);List<List<Integer>> big = new ArrayList<>();big.add(r0);big.add(r1);big.add(r2);big.add(r3);System.out.println(test2.canVisitAllRooms(big));System.out.println(visited);}
}

编程愉快!

刷题记录:广搜 | leetcode-841. 钥匙和房间 2023/6/5相关推荐

  1. LeetCode 841. 钥匙和房间(DFS/BFS)

    文章目录 1. 题目 2. 解题 2.1 DFS 2.2 BFS 1. 题目 有 N 个房间,开始时你位于 0 号房间.每个房间有不同的号码:0,1,2,-,N-1,并且房间里可能有一些钥匙能使你进入 ...

  2. C++性能之战(4)--LeetCode 841 钥匙和房间(cin和cout加速)

    希望大家收藏: 本文持续更新地址:https://haoqchen.site/2018/09/04/LeetCode841/ 今天刷841的时候看到一个大神写的巨高级的代码.在这里分享以下.这位大神用 ...

  3. LeetCode刷题记录15——21. Merge Two Sorted Lists(easy)

    LeetCode刷题记录15--21. Merge Two Sorted Lists(easy) 目录 LeetCode刷题记录15--21. Merge Two Sorted Lists(easy) ...

  4. LeetCode刷题记录14——257. Binary Tree Paths(easy)

    LeetCode刷题记录14--257. Binary Tree Paths(easy) 目录 前言 题目 语言 思路 源码 后记 前言 数据结构感觉理论简单,实践起来很困难. 题目 给定一个二叉树, ...

  5. LeetCode刷题记录13——705. Design HashSet(easy)

    LeetCode刷题记录13--705. Design HashSet(easy) 目录 LeetCode刷题记录13--705. Design HashSet(easy) 前言 题目 语言 思路 源 ...

  6. LeetCode刷题记录12——232. Implement Queue using Stacks(easy)

    LeetCode刷题记录12--232. Implement Queue using Stacks(easy) 目录 LeetCode刷题记录12--232. Implement Queue usin ...

  7. LeetCode刷题记录11——290. Word Pattern(easy)

    LeetCode刷题记录11--290. Word Pattern(easy) 目录 LeetCode刷题记录11--290. Word Pattern(easy) 题目 语言 思路 源码 后记 题目 ...

  8. LeetCode刷题记录10——434. Number of Segments in a String(easy)

    LeetCode刷题记录10--434. Number of Segments in a String(easy) 目录 LeetCode刷题记录9--434. Number of Segments ...

  9. LeetCode刷题记录9——58. Length of Last Word(easy)

    LeetCode刷题记录9--58. Length of Last Word(easy) 目录 LeetCode刷题记录9--58. Length of Last Word(easy) 题目 语言 思 ...

最新文章

  1. [原] Unity调用android版新浪微博
  2. 16进制ff转化为二进制_3秒钟快速转换十六进制为二进制
  3. 静态成员变量和非静态成员变量的5个主要区别
  4. Java开发代码规范之编程规约---命名风格
  5. Android电视关闭的闪屏动画效果
  6. js 实现轻量ps_简单轻量的池实现
  7. OpenSSL 创建自签名证书
  8. 在线考试新入.html,JSP+SSM+MySql实现的在线考试系统毕设指导思路模板
  9. python编程入门与案例详解-Python程序设计案例课堂
  10. hdu 1575 Tr A (二分矩阵)
  11. varchar和varchar2的联系与区别
  12. c语言运算符优先级(c语言运算符优先级由高到低的顺序)
  13. 用python函数画德国国旗代码_给我一面国旗 python帮你实现
  14. react.js 原生文字下划线标注功能开发
  15. 2017关于自学PHP的方法
  16. 前后端传图片用base64好吗_Base64是什么?前端用Base64加载图片到底好不好?
  17. Occlusion Culling(遮挡剔除)
  18. Python爬虫抓取网页图片
  19. Java(回文数--比较简单的写法)
  20. 基于BERT+BiLSTM+CRF的中文景点命名实体识别

热门文章

  1. unity内购-Google支付(unity In-App Purchasing)
  2. mac 自带 java 环境_在mac上搭建了Java 环境,谨以此文写给自己
  3. 禁忌搜索算法(tabu search)解决TSP及其Matlab代码
  4. 太空射击第10课: Score (繪畫和文字)
  5. 浪潮云洲链接入“星火•链网”,走向工业互联网的星辰大海
  6. 宝藏又小众的元宵节元素素材网站分享
  7. 雷军:如果不是年轻时不懂事,我就是世界首富
  8. 讨教大学:2018通信工程师考试什么时候考,通信工程师证有用吗?
  9. iOS 开发中如何隐藏UINavigationBar
  10. 截图工具 Snagit