《剑指 Offer》专项突破版 - 面试题 109 : 开密码锁(C++ 实现)

题目链接开密码锁

题目

一个密码锁由 4 个环形转轮组成,每个转轮由 0 ~ 9 这 10 个数字组成。每次可以上下拨动一个转轮,如可以将一个转轮从 0 拨到 1,也可以从 0 拨到 9。密码锁有若干死锁状态,一旦 4 个转轮被拨到某个死锁状态,这个锁就不可能打开。密码锁的状态可以用一个长度为 4 的字符串表示,字符串中的每个字符对应某个转轮上的数字。输入密码锁的密码和它的所有死锁状态,请问至少需要拨动转轮多少次才能从起始状态 "0000" 开始打开这个密码锁?如果锁不可能打开,则返回 -1。

例如,如果某个密码锁的密码是 "0202",它的死锁状态列表是 ["0102", "0201"],那么至少需要拨动转轮 6 次才能打开这个密码锁,一个可行的开锁状态序列是 "0000"->"1000"->"1100"->"1200"->"1201"->"1202"->"0202"。虽然序列 "0000"->"0100"->"0200"->"0201"->"0202" 更短,只需要拨动 4 次转轮,但它包含死锁状态 "0201",因此这是一个无效的开锁序列。

分析

密码锁 4 个转轮上的数字定义了密码锁的状态,转动密码锁的转轮可以改变密码锁的状态。一般而言,如果一个问题是关于某事物状态的改变,那么可以考虑把问题转换成图搜索的问题。事物的每个状态是图中的一个节点,如果一个状态能够转变到另一个状态,那么这两个状态对应的节点之间有一条边相连

对于这个问题而言,密码锁的每个状态都对应着图中的一个节点,如状态 "0000" 是一个节点,"0001" 是另一个节点。如果转动某个转轮一次可以让密码锁从一个状态转移到另一个状态,那么这两个状态之间有一条边相

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值