由于这个问题,涉及了很多知识,例如数据结构里面的哈希表,c++中的迭代器,因此,需要对于每一个疑惑逐一击破。

问题描述

You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'. The wheels can rotate freely and wrap around: for example we can turn '9' to be '0', or '0' to be '9'. Each move consists of turning one wheel one slot.

The lock initially starts at '0000', a string representing the state of the 4 wheels.

You are given a list of deadends dead ends, meaning if the lock displays any of these codes, the wheels of the lock will stop turning and you will be unable to open it.

Given a target representing the value of the wheels that will unlock the lock, return the minimum total number of turns required to open the lock, or -1 if it is impossible.

Example 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".

Example 2:

Input: deadends = ["8888"], target = "0009"
Output: 1
Explanation:
We can turn the last wheel in reverse to move from "0000" -> "0009".

Example 3:

Input: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888"
Output: -1
Explanation:
We can't reach the target without getting stuck.

Example 4:

Input: deadends = ["0000"], target = "8888"
Output: -1

Note:

  1. The length of deadends will be in the range [1, 500].
  2. target will not be in the list deadends.
  3. Every string in deadends and the string target will be a string of 4 digits from the 10,000 possibilities '0000' to '9999'.

参考答案

 class Solution {
public:
int openLock(vector<string>& deadends, string target) {
unordered_set<string> deadlock(deadends.begin(), deadends.end());
if (deadlock.count("")) return -;
int res = ;
unordered_set<string> visited{{""}};
queue<string> q{{""}};
while (!q.empty()) {
++res;
for (int k = q.size(); k > ; --k) {
auto t = q.front(); q.pop();
for (int i = ; i < t.size(); ++i) {
for (int j = -; j <= ; ++j) {
if (j == ) continue;
string str = t;
str[i] = ((t[i] - '') + + j) % + '';
if (str == target) return res;
if (!visited.count(str) && !deadlock.count(str)) q.push(str);
visited.insert(str);
}
}
}
}
return -;
}
};

补充知识

迭代器

正如我们知道的,程序中包含了大量的迭代,这些迭代都是在循环中进行的,比如for。

迭代(Iteration):是一种行为,对于某个特定容器,进行遍历的行为。

可迭代对象(Iterable):是一个容器,例如set,list,vector等等,一堆数据装在里面,而这个容器可以进行迭代操作。

那什么是迭代器(iterator)呢?

迭代器,就好像是一个可以供人们操作的装置对象,其中包含了数据,以及可以进行操作的按钮(例如c++中的begin,end等等[1]),这样我们可以很方便的使用并且操作打包好的数据。

另外还有一个问题,比如下面这个例子[2]:

std::vector<int> v;
for (vector<int>::iterator iter = v.begin(); iter != v.end(); ++iter)
{
// do someting with iter
}

v 能懂,是一个vector。vector<int> 类型的 iterator 也可以懂,但什么是 v.begin() ?

[1] 的解释是返回幵始迭代器。what the fxxk? 什么是开始迭代器?难道迭代器不是可以操纵的对象么?我查了很多的中文网站和博客,似乎都没有很理想的解释。后来查到了它的英文解释:begin() function is used to return an iterator pointing to the first element of the vector container.

这样就清楚好多了, v.begin() 是一个迭代器,特殊的是,它是指向容器中第一个元素的迭代器。

另外,也要注意 v.end() ,它也是迭代器,但它是 指向容器最后元素的 下一个位置的 迭代器。

使用例子[3]

#include <iostream>
#include <vector>
using namespace std; int main()
{
// declaration of vector container
vector<int> myvector{ , , , , }; // using end() to print vector
for (auto it = myvector.begin() ; it != myvector.end(); ++it)
cout << ' ' << *it;
return ;
}

输出为:

1 2 3 4 5

另外,不用费心考虑iteator的类型,直接使用auto即可

 

insert & find

使用迭代器的好处,就是可以使用一堆提供好的函数,这个例子中可以找到 insert 和 find 。
方式就如答案所示,详细的可以参看:http://c.biancheng.net/view/570.html
 

t[i] - '0' 是个什么?

第17行,出现了 str[i] = (( t[i] - '0' ) + 10 + j) % 10 + '0' 这一行,所以我陷入了迷思,为什么string类型可以进行运算。后来通过print进行测试。
发现,如果对'0'进行加减操作,会出现这样的结果。
运行如下代码:
 #include <iostream>
#include <string> using namespace std; int main()
{
string str = "";
string result ;
for(int i = -; i<;i++){
result[] = str[] + i;
cout<<result<<endl;
} return ;
}

可以得到:

'
(
)
+
,
.
/

我们会发现,直接对 string 进行加减操作,直接会显示上一个字符和之后的字符。因此,17行源代码的意思是:

减去‘0’,即获得原来的 t[i] 对于‘0’的偏移量,这是一个 int 类型。基于该偏移量,进行加减1的操作(+j),然后再次添加‘0’,将偏移量变成 string 类型。而 +10 和 %10 操作,为了防止 0-1 = -1 操作的发生,或者是 9+1 = 10 的情况发生。-1对应着 9 (9 = 0+10-1),而 10 对应着 0 (0 = 9+1 +10 对 10 取余是 0)。

很舒服。

[1]: http://c.biancheng.net/view/409.html

[2]:https://qinglinmao8315.github.io/c++/2018/03/07/how-std-vector-end-work.html

[3]: https://www.geeksforgeeks.org/vectorbegin-vectorend-c-stl/

LC 752 Open the Lock的更多相关文章

  1. LeetCode 752. Open the Lock

    原题链接在这里:https://leetcode.com/problems/open-the-lock/ 题目: You have a lock in front of you with 4 circ ...

  2. [LeetCode] 752. Open the Lock 开锁

    You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots: '0', '1', '2', '3', ...

  3. 【LeetCode】752. Open the Lock 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  4. golang锁

    golang锁包:https://studygolang.com/pkgdoc sync.Mutex是一个互斥锁 var lock sync.Mutex 加锁段在中 lock.lock() lock. ...

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

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

  6. 算法与数据结构基础 - 广度优先搜索(BFS)

    BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...

  7. leetcode 学习心得 (4)

    645. Set Mismatch The set S originally contains numbers from 1 to n. But unfortunately, due to the d ...

  8. All LeetCode Questions List 题目汇总

    All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...

  9. LeetCode All in One 题目讲解汇总(转...)

    终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 如果各位看官们,大神们发现了任何错误,或是代码无法通 ...

随机推荐

  1. CSS简单选择器的学习笔记

    我们知道通过CSS定义页面样式的时候要用到各种各样的选择器,正确的使用选择器是我们能够正确使用CSS做页面样式的基础.下面是我学习选择器的一个简易笔记,举一些简单的例子. 为了方便展示,我选择在内部的 ...

  2. gitlab使用指南

    gitlab是公司内部搭建的用于管理代码项目的类似于github的系统. 登录注册 注册时使用的名称和邮箱请按照公司内部格式进行信息填写. 在注册完成以后有可能会向邮箱里发送一个注册邮件,如果要求发送 ...

  3. Dubbo 节点telnet测试

        Dubbo 节点telnet测试 本地安装telnet客户端 Telnet 服务地址 端口 如telnet 127.0.0.1 1234 出现此对话框表示连接成功 输入status –l 会显 ...

  4. 服务器多进程powershell导致服务器瘫痪问题解决

    1.公司服务器多次无法访问,经查多由于开启了多个powershell进程,网上查询是被挖矿了,可通过将powershell应用程序重命名解决. 2.然而重命名的时候发现需要trustedInstall ...

  5. Java web 实验三部分资料上传

    花好月圆系列 貂蝉 黄月英 孙尚香 甄姬 标准包 魏 曹操 司马懿 郭嘉 甄姬 张辽 许褚 夏侯惇 蜀 刘备 关羽 张飞 诸葛亮 黄月英 赵云 马超 吴 孙权 孙尚香 周瑜 大乔 甘宁 吕蒙 群 吕布 ...

  6. Ajax传递复杂对象报415

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  7. map,实现技巧,id

    cf #include<iostream> #include<cstdio> #include<algorithm> #include<vector> ...

  8. spark MLlib的 pipeline方式

    spark mllib的pipeline,是指将多个机器学习的算法串联到一个工作链中,依次执行各种算法. 在Pipeline中的每个算法被称为"PipelineStage",表示其 ...

  9. mysql表的模糊查询

    查询库下所有的表名 SELECT table_name FROM information_schema.tables WHERE table_schema='库名' 模糊表名查询 SELECT tab ...

  10. 在spring的业务层获取request,response

    1.直接通过controller层获取到传输到业务层2.SpringMVC提供的RequestContextHolder可以直接获取代码: RequestAttributes requestAttri ...