Leetcode 每日一题和每日一题的下一题刷题笔记 25/30
写在前面
这是我参与更文挑战的第25天,活动详情查看:更文挑战
快要毕业了,才发现自己被面试里的算法题吊起来锤。没办法只能以零基础的身份和同窗们共同加入了力扣刷题大军。我的同学们都非常厉害,他们平时只是谦虚,口头上说着自己不会,而我是真的不会。。。乘掘金鼓励新人每天写博客,我也凑个热闹,记录一下每天刷的前两道题,这两道题我精做。我打算每天刷五道题,其他的题目嘛,也只能强行背套路了,就不发在博客里了。
本人真的只是一个菜鸡,解题思路什么的就不要从我这里参考了,编码习惯也需要改进,各位如果想找刷题高手请教问题我觉得去找 宫水三叶的刷题日记 这位大佬比较好。我在把题目做出来之前尽量不去看题解,以免和大佬的内容撞车。
另外我也希望有得闲的大佬提供一些更高明的解题思路给我,欢迎讨论哈!
好了废话不多说开始第二十五天的前两道题吧!
2021.6.25 每日一题
这道题感觉挺难的,为什么放中等题里面。。。我使用双向 BFS,这个思路应该是大多数人努努力能想到的,然后看题解居然能用 A*。。。好吧,看来是我题做的不够多。
先根据题意把转旋钮的函数实现一下,转一下旋钮,加一个或者减一个,遇到两头的 0 和 9 是特殊情况,0 减一个实际上是 -1,这时候其实应该减 -9,同理,9 加一个实际上是 10,这时候其实应该加 -9。
int steps(int num)
{
if(num == 10)
return -9;
if(num == -1)
return -9;
else return 1;
}
后面就是双向 BFS 了,能这么用有一个条件,问题的搜索空间肯定是满足局部最优和全局最优是同一个,不然这么双向搜索很容易掉到两个坑里面,这样就再也出不来了。
class Solution {
public:
int seen[10000];
int ans = -1;
bool dead[10000];
int q[10000];
int openLock(vector<string>& deadends, string target) {
for(auto d : deadends){
int tmp = stoi(d);
dead[tmp] = 1;
}
if(dead[0])return -1;
if(target == "0000") return 0;
int tar=stoi(target);
bfs(tar);
return ans;
}
int steps(int num)
{
if(num == 10)
return -9;
if(num == -1)
return -9;
else return 1;
}
void bfs(int target)
{
int hh=0,tt=0;
q[0] = 0;
while(hh <= tt){
auto t = q[hh++];
int prev = t;
for(int i = 1 ; i <= 1000 ; i *= 10){
int num = t / i % 10;
int temp = t;
// ++
int tmp = temp + steps(num + 1) * i;
if(!seen[tmp] && !dead[tmp]){
q[tt++] = tmp;
seen[tmp] = seen[prev] + 1;
}
// --
tmp = temp - steps(num - 1) * i;
if(!seen[tmp] && !dead[tmp]){
q[tt++] = tmp;
seen[tmp] = seen[prev] + 1;
}
}
if(seen[target] != 0){
ans = seen[target];
break;
}
}
}
};
可以刷一下运行,这是最好看的结果。
2021.6.25 每日一题下面的题
这道题经常在面试题的选择题里出现,手画还能说两句,写代码估计要反应一会,我这方面估计还得加强。
给一个前序遍历和中序遍历,把树结构整理出来。根据这两种遍历的特点,首先可以确定整棵树的根节点是中序遍历的第一个点,整棵树最左边的叶子节点是前序遍历的第一个点。然后根据这种有根有左的特点,我们主要就是玩左子树这个概念了。根左右和左根右在右不出现的情况下正好是相反的,那我正好记录一个 root_and_left,暂时不带“右”玩就行。这个 root_and_left 是一个栈,要和另一个指针配合起来。指针 index 是中序遍历上的一个指针,我用它来确定当前在给谁找上级关系。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (!preorder.size()) {
return nullptr;
}
TreeNode* root = new TreeNode(preorder[0]);
stack<TreeNode*> stk;
stk.push(root);
int inorderIndex = 0;
for (int i = 1; i < preorder.size(); i++) {
int preorderVal = preorder[i];
TreeNode* node = stk.top();
if (node->val != inorder[inorderIndex]) {
node->left = new TreeNode(preorderVal);
stk.push(node->left);
}
else {
while (!stk.empty() && stk.top()->val == inorder[inorderIndex]) {
node = stk.top();
stk.pop();
inorderIndex++;
}
node->right = new TreeNode(preorderVal);
stk.push(node->right);
}
}
return root;
}
};
小结
双向BFS
找栈顶,找不到就认主,找到就归队。
参考链接
无