Leetcode 每日一题和每日一题的下一题刷题笔记 17/30
写在前面
这是我参与更文挑战的第17天,活动详情查看:更文挑战
快要毕业了,才发现自己被面试里的算法题吊起来锤。没办法只能以零基础的身份和同窗们共同加入了力扣刷题大军。我的同学们都非常厉害,他们平时只是谦虚,口头上说着自己不会,而我是真的不会。。。乘掘金鼓励新人每天写博客,我也凑个热闹,记录一下每天刷的前两道题,这两道题我精做。我打算每天刷五道题,其他的题目嘛,也只能强行背套路了,就不发在博客里了。
本人真的只是一个菜鸡,解题思路什么的就不要从我这里参考了,编码习惯也需要改进,各位如果想找刷题高手请教问题我觉得去找 宫水三叶的刷题日记 这位大佬比较好。我在把题目做出来之前尽量不去看题解,以免和大佬的内容撞车。
另外我也希望有得闲的大佬提供一些更高明的解题思路给我,欢迎讨论哈!
好了废话不多说开始第十七天的前两道题吧!
2021.6.17 每日一题
这题目真是绝了,判断正常的数字,回忆起了被谭浩强小红书支配的恐惧。。。各种各样奇怪的选择题让你选合法的数字。
这道题给人一种在玩 FPGA 的感觉。提到 FPGA,最重要的就是状态机了,这道题当然可以用状态机来做。请不要过度神化状态机(自动机),反正我感觉学过编译原理的专业都喜欢神化自动机,但是基本上被数电折磨的死去活来的专业都拿状态机当自己的朋友。实际上不管叫它状态机还是自动机它都是一个东西,KMP 算法里会使用到它,正则的基础思想也是它,搞 FPGA 一定会用这个东西来设计自己的小系统工作流程。
所以,实际上分类讨论,正则,翻译,这些解题思路背后真正用到的还是状态机。。。只是这些解题思路用到了语言里封装好的工具。那么我们自己要如何使用最原始最本质的状态机思想来解这道题呢?建议各位先去看这道题的精选回答,我觉得这个题解比官方题解写的要好。
状态机一定有一个初始状态和若干可接受状态,可接收状态的数量看设计者对问题的理解以及分割,毕竟状态机是为了方便人处理问题而出现的,不是专门拿出来难为人的东西。这个东西就是用来规范分情况讨论和拆分子问题的思维步骤的工具。我认为一开始读入若干空格是初始状态,然后就是读入符号,然后读入数字,然后读入小数点,然后读入数字,然后读入科学计数法的标志 e
或 E
,然后读入符号,然后读入数字,最后结束的时候可能会读入若干空格,这样最复杂的数字读入流程就结束了。然后从最复杂的流程开枝散叶看中间那些步骤可以跳过,比如说符号可以跳过,比如说小数点可以跳过,比如说科学计数法标志可以跳过。然后就是整理思路画出状态转移图(不要把状态机和动态规划混为一谈,状态转移图也是为了理思路,不重不漏,方便阅读就行),我这里借用一下精选回答的状态转移图:
不知各位能否看懂,图里面从左到右0到5这个状态是最复杂情况,其他线描述的是可以跳步的情况,如果一个字符串读入,还没有到最终情况就读完了,那么这种停在半中央挡道的东西都不是正常的数,停在半中央挡道并没有转移到我们的可接受状态,理所当然是不能被接受的状态。
如果这个图没有看懂,那么看一下这张图对应的状态跳转表,看状态跳转表就跟做心理测试一样,这道题你回答了这个选项,请你跳转到某某问题上继续测试,最后会落在一系列心里测试结果的某一种里,这种状态转移表应该是最好接受的状态机的描述形式了。
state | blank | +/- | 0-9 | . | e/E | other |
---|---|---|---|---|---|---|
0 | 0 | 1 | 6 | 2 | -1 | -1 |
1 | -1 | -1 | 6 | 2 | -1 | -1 |
2 | -1 | -1 | 3 | -1 | -1 | -1 |
3 | 8 | -1 | 3 | -1 | 4 | -1 |
4 | -1 | 7 | 5 | -1 | -1 | -1 |
5 | 8 | -1 | 5 | -1 | -1 | -1 |
6 | 8 | -1 | 6 | 3 | 4 | -1 |
7 | -1 | -1 | 5 | -1 | -1 | -1 |
8 | 8 | -1 | -1 | -1 | -1 | -1 |
作者:user8973 链接:leetcode-cn.com/problems/va… 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
带上原文链接,各位看不懂我在说啥去看原文就行。我觉得问题说到这个份上已经完全说明白了,之后就是把这些东西翻译成代码。
class Solution {
public:
bool isNumber(string s) {
if (s.empty()) {
return false;
}
int n = s.size();
int state = 0;
vector<bool> finals({0, 0, 0, 1, 0, 1, 1, 0, 1});
vector<vector<int>> transfer({
{ 0, 1, 6, 2, -1, -1},
{-1, -1, 6, 2, -1, -1},
{-1, -1, 3, -1, -1, -1},
{ 8, -1, 3, -1, 4, -1},
{-1, 7, 5, -1, -1, -1},
{ 8, -1, 5, -1, -1, -1},
{ 8, -1, 6, 3, 4, -1},
{-1, -1, 5, -1, -1, -1},
{ 8, -1, -1, -1, -1, -1},
});
for (int i = 0; i < n; i++) {
state = transfer[state][_make(s[i])];
if(state < 0) return false;
}
return finals[state];
}
private:
int _make(const char& c) {
switch(c) {
case ' ': return 0;
case '+': return 1;
case '-': return 1;
case '.': return 3;
case 'e': return 4;
case 'E': return 4;
default: return _number(c);
}
}
int _number(const char& c) {
if (c >= '0' && c <= '9'){
return 2;
} else {
return 5;
}
}
};
2021.6.17 每日一题下面的题
这题可以直接秒了,简单题面试官就喜欢看你的代码规范,一般工程里传这种东西都是这么写 vector<int> runningSum(const vector<int>& nums)
,然后实现的时候自己复制一份自己随便玩,原来传进来的不要乱改。
小结
状态机判断合法的数字,简单题注重代码规范
参考链接
无