文章目录

  • 1 题目理解
  • 2 BFS
  • 3 用int构建状态

1 题目理解

一个钟表有4个槽,每个槽可以停在0-9,10个状态。钟表每个槽的轮子可以转,例如可以从0转到9,也可以从0转到1。
钟表的起始状态是"0000"。每个数字代表一个槽的状态。
输入:字符串数组deadends,表示不能死亡状态,进入这个状态钟表就被锁住了,不能动了。输入字符串target表示想要达到的状态。
输出:到达最终状态的最少需要多少步。如果不能达到则为-1。
规则:每一步,钟表只能转动一个槽,只能转一下,
例子:
Input: deadends = [“0201”,“0101”,“0102”,“1212”,“2002”], target = “0202”
Output: 6
Explanation:
A sequence of valid moves would be “0000” -> “1000” -> “1100” -> “1200” -> “1201” -> “1202” -> “0202”.
Note that a sequence like “0000” -> “0001” -> “0002” -> “0102” -> “0202” would be invalid,
because the wheels of the lock become stuck after the display becomes the dead end “0102”.

2 BFS

要求最短路径长度,所以使用BFS。
在某一种状态下,要先判断这个状态能不能动。如果deadends包含target,则不能达到。

在正常状态下,某一状态的变化,可以变化其中一个槽,变化的动作可以是加1,也可以是减1。变化之后进入新的状态。

    class Solution {public int openLock(String[] deadends, String target) {Set<String> set = new HashSet<String>();for(String str : deadends){set.add(str);}String start = "0000";if(set.contains(target) || set.contains(start)) return -1;Queue<String> queue = new LinkedList<String>();queue.offer(start);set.add(start);int step = 0;while(!queue.isEmpty()){int size = queue.size();//System.out.println(queue);for(int r=0;r<size;r++){if(target.equals(queue.peek())){return step;}char[] current = queue.poll().toCharArray();for(int i=0;i<4;i++){char ch = current[i];int v = current[i]-48;current[i] = (char)(((v+1+10)%10)+48);String newState = new String(current);if(!set.contains(newState)){queue.offer(newState);set.add(newState);}current[i] = (char)(((v-1+10)%10)+48);String newState2 = new String(current);if(!set.contains(newState2)){queue.offer(newState2);set.add(newState2);}current[i] = ch;}}step++;}return -1;}}

时间复杂度:可以选择的数据范围n=10,状态位数x=4,O(104∗4∗4)O(10^4*4*4)O(104∗4∗4)。最坏情况下有10410^4104种状态。每个状态可以有4*2=8种变化,所以是O(x)。枚举后得到新的状态,构建字符串,需要O(x)时间。所以最终结果是:O(nx∗x∗x)O(n^x*x*x)O(nx∗x∗x)

3 用int构建状态

因为每个位置的值在0-9之间,可以用4位二进制表示,我们可以用int表示状态,这样速度方面会更快。

class Solution {private final static int[] increments = new int[]{ 1, -1 };public int openLock(String[] deadends, String target) {int step = 0;Set<Integer> used = new HashSet<Integer>();String start = "0000";int startInt = 0;int targetInt = buildState(target);for(String deadend : deadends){used.add(buildState(deadend));}if(used.contains(startInt) || used.contains(targetInt)) return -1;used.add(startInt);Queue<Integer> queue = new LinkedList<Integer>();queue.offer(startInt);while(!queue.isEmpty()){int size =queue.size();for(int i=0;i<size;i++){int nodeInt = queue.poll();if(nodeInt==targetInt) return step;for(int increment : increments){for(int j =0;j<4;j++){int newNode = updateState(nodeInt,j,increment);if(!used.contains(newNode)){used.add(newNode);queue.offer(newNode);}}}}step++;}return -1;}private int updateState(int state, int d, int inc) {int mask = (1 << 4) - 1;int[] num = new int[]{state & mask,(state >> 4) & mask,(state >> 8) & mask,(state >> 12) & mask};int n = num[d];if (n == 0 && inc == -1) {num[d] = 9;} else if (n == 9 && inc == 1) {num[d] = 0;} else {num[d] += inc;}int res = 0;for (int i = 3; i >= 0; i--) {res <<= 4;res |= num[i];}return res;}private int buildState(String state) {char[] c = state.toCharArray();int res = 0;for (int i = 0; i < c.length; i++) {int d = c[i] - '0';res <<= 4;res |= d;}return res;}
}

752. Open the Lock相关推荐

  1. leetcode 752. Open the Lock | 752. 打开转盘锁(BFS)

    题目 https://leetcode.com/problems/open-the-lock/ 题解 先写了个 DFS,超时了. 看了下 Related Topics,提示说应该是 BFS.这已经不是 ...

  2. 【Breadth-first Search 】752. Open the Lock

    输入:deadends 是指针终止状态列表,target 是希望到达的指针状态,初始化指针状态是0000. 输出:如果指针能够到达target状态,则变化的最少步骤是多少.如果不能到达target状态 ...

  3. leetcode刷题规划

    LeetCode精华题目列表[刷题规划系列] – TuringPlanet 目录 算法题到底在考察什么? 题目列表 Array String Linked List Queue Stack Advan ...

  4. LeetCode刷题之python解法(持续更新)

    1. Two Sum 4行 class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:d = {}fo ...

  5. Leet Code 力扣 - - 最短最优雅python解法带解析汇总

    Leet Code 刷题笔记 - - 不求最快最省,但求最短最优雅 前言 代码精炼是 Python 的核心,同时能够反应对于语言的熟练程度,本项目目的在于汇总 leet code 最短最优雅的解法,拒 ...

  6. leetcode算法练习 JavaScript实现

    leetcode 表格内容由spider.js从leetcode-cn.com爬取. 已做题目答案也从leetcode-cn.com中爬取并生成文件. 解题进度:已解决 140/637 - 简单 94 ...

  7. LeetCode All in One 题目讲解汇总(持续更新中...)

    原文地址:https://www.cnblogs.com/grandyang/p/4606334.html 终于将LeetCode的大部分题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开 ...

  8. 【LeetCode】863. All Nodes Distance K in Binary Tree 解题报告(Python)

    [LeetCode]863. All Nodes Distance K in Binary Tree 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...

  9. E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)

    问题详细提示如下: 当你执行sudo apt-get XXX这种命令时出现类似下面的输出错误: E: Could not get lock /var/lib/dpkg/lock - open (11 ...

最新文章

  1. 【c语言】蓝桥杯算法训练 整除问题
  2. 日活4000万,占据22%手游时长份额的竟然是……(文末有彩蛋)
  3. 原型与原型链的简单理解
  4. mysql中find_in_set_mysql中find_in_set()函数的使用详解
  5. sql语句中的时间查询
  6. Java排查问题随笔
  7. mysql_fetch_bit_mysql_fetch_array()
  8. linux while read文件,linux shell脚本用while read逐行读取文本的问题
  9. ser crt linux 乱码,大师为你解决securecrt中文乱码【处理指南】
  10. 【java笔记】TCP通信程序
  11. SR 学习记录----JUNOS为例
  12. MVC/POJO/POJI/DAO/DTO/VO
  13. PHP 生成PDF文件并向PDF添加图片
  14. oracle裁员原因_导致甲骨文全球性裁员的原因有哪些?
  15. 抖音壁纸小程序怎么做?教你开通和对接流量主拥有自己的小程序
  16. Android 消息通知栏用法详解(一)
  17. Linux的主机名基础
  18. 如何安装ubuntu kylin(优麒麟)?
  19. python的tell和seek_4.2Python文件基本操作2:tell、seek
  20. 以Transaction的生命周期为线索剖析Libra核心组件

热门文章

  1. 不确定屏幕大小的弹窗垂直居中(用了box方法)
  2. Pagination(分页) 从前台到后端总结
  3. Ubuntu下一个openldapserver部署步骤
  4. VMware下Windows Server 2012添加新磁盘
  5. htaccess文件,强大的功能
  6. 面向对象之多态性(基类引用可以指向子类)
  7. PMP读书笔记(第9章)
  8. 关于CI框架引入CSS与JS文件
  9. SVN 405错误
  10. java node websocket_nodejs怎么实现webSocket接口即时通讯服务?