提交 66b8b16b 编写于 作者: 每日一练社区's avatar 每日一练社区

add exercises

上级 4e68b806

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
{
"node_id": "algorithm-1457c70ac29a46a795c3a8aa8de0d34f",
"keywords": [
"leetcode",
"二叉树的锯齿形层序遍历"
],
"children": [],
"export": [
"solution.json"
],
"title": "二叉树的锯齿形层序遍历"
}
\ No newline at end of file
<p>给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。</p>
<p>例如:<br />
给定二叉树 <code>[3,9,20,null,null,15,7]</code>,</p>
<pre>
3
/ \
9 20
/ \
15 7
</pre>
<p>返回锯齿形层序遍历如下:</p>
<pre>
[
[3],
[20,9],
[15,7]
]
</pre>
#include <vector>
#include <queue>
#include <cstddef>
using std::vector;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution
{
public:
vector<vector<int>> zigzagLevelOrder(TreeNode *root)
{
vector<vector<int>> retv;
if (!root)
return retv;
std::queue<TreeNode *> q;
q.push(root);
bool reverse = false;
vector<int> v;
for (int cur_level_sz = 1, next_level_sz = 0; !q.empty();)
{
TreeNode *node = q.front();
q.pop();
v.push_back(node->val);
--cur_level_sz;
if (node->left)
{
q.push(node->left);
++next_level_sz;
}
if (node->right)
{
q.push(node->right);
++next_level_sz;
}
if (!cur_level_sz)
{
retv.push_back(reverse ? vector<int>(v.crbegin(), v.crend()) : v);
v.clear();
cur_level_sz = next_level_sz;
next_level_sz = 0;
reverse = !reverse;
}
}
return retv;
}
};
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "d55fa143ea4b4a9b9cfc24a1e68e0e64"
}
\ No newline at end of file
# 二叉树的锯齿形层序遍历
<p>给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。</p>
<p>例如:<br />
给定二叉树 <code>[3,9,20,null,null,15,7]</code>,</p>
<pre>
3
/ \
9 20
/ \
15 7
</pre>
<p>返回锯齿形层序遍历如下:</p>
<pre>
[
[3],
[20,9],
[15,7]
]
</pre>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
```
### after
```cpp
```
## 答案
```cpp
class Solution
{
public:
vector<vector<int>> zigzagLevelOrder(TreeNode *root)
{
vector<vector<int>> result;
if (root == NULL)
{
return result;
}
deque<TreeNode *> node_queue;
node_queue.push_back(root);
node_queue.push_back(NULL);
deque<int> level_list;
bool is_order_left = true;
while (node_queue.size() > 0)
{
TreeNode *curr_node = node_queue.front();
node_queue.pop_front();
if (curr_node != NULL)
{
if (curr_node->left != NULL)
{
node_queue.push_back(curr_node->left);
}
if (curr_node->right != NULL)
{
node_queue.push_back(curr_node->right);
}
}
else
{
vector<int> tmp;
for (int a : level_list)
{
tmp.push_back(a);
}
result.push_back(tmp);
level_list.clear();
if (node_queue.size() > 0)
{
node_queue.push_back(NULL);
}
is_order_left = !is_order_left;
}
}
return result;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
vector<vector<int>> zigzagLevelOrder(TreeNode *root)
{
if (root == NULL)
return {};
vector<vector<int>> res;
int flag = 1;
stack<TreeNode *> a, b;
a.push(root);
while (!a.empty() || !b.empty())
{
vector<int> cur;
while (flag == 1 && !a.empty())
{
root = a.top();
cur.push_back(root->val);
a.pop();
if (root->left != NULL)
b.push(root->left);
if (root->right != NULL)
b.push(root->right);
}
while (flag == -1 && !b.empty())
{
root = b.top();
cur.push_back(root->val);
b.pop();
if (root->right != NULL)
a.push(root->right);
if (root->left != NULL)
a.push(root->left);
}
flag = -1 * flag;
res.push_back(cur);
}
return res;
}
};
```
### B
```cpp
class Solution
{
public:
vector<vector<int>> zigzagLevelOrder(TreeNode *root)
{
vector<vector<int>> ans;
if (!root)
return ans;
queue<TreeNode *> qnode;
bool orderByLeft = true;
qnode.push(root);
while (!qnode.empty())
{
int levelSize = qnode.size();
deque<int> level;
for (int i = 0; i < levelSize; i++)
{
auto curNode = qnode.front();
qnode.pop();
if (orderByLeft)
{
level.push_back(curNode->val);
}
else
{
level.push_front(curNode->val);
}
if (curNode->left != NULL)
qnode.push(curNode->left);
if (curNode->right != NULL)
qnode.push(curNode->right);
}
orderByLeft = !orderByLeft;
vector<int> curlevel{level.begin(), level.end()};
ans.push_back(curlevel);
}
return ans;
}
};
```
### C
```cpp
class Solution
{
public:
vector<vector<int>> zigzagLevelOrder(TreeNode *root)
{
if (!root)
return {};
vector<vector<int>> res;
queue<TreeNode *> q{{root}};
int cnt = 0;
while (!q.empty())
{
vector<int> oneLevel;
for (int i = q.size(); i > 0; i--)
{
TreeNode *t = q.front();
q.pop();
oneLevel.push_back(t->val);
if (t->left)
q.push(t->left);
if (t->right)
q.push(t->right);
}
if (cnt % 2 == 1)
reverse(oneLevel.begin(), oneLevel.end());
res.push_back(oneLevel);
cnt++;
}
return res;
}
};
```
### D
```cpp
class Solution
{
public:
vector<vector<int>> zigzagLevelOrder(TreeNode *root)
{
vector<vector<int>> results;
if (root == NULL)
{
return results;
}
zigzagLevelOrderDFS_helper(root, 0, results);
return results;
}
void zigzagLevelOrderDFS_helper(TreeNode *node, int level, vector<vector<int>> &results)
{
if (level >= results.size())
{
vector<int> new_level;
new_level.push_back(node->val);
results.push_back(new_level);
}
else
{
if (level % 2 == 0)
{
results[level].push_back(node->val);
}
else
{
results[level].insert(results[level].begin(), node->val);
}
}
if (node->left != NULL)
{
zigzagLevelOrderDFS_helper(node->left, level + 1, results);
}
if (node->right != NULL)
{
zigzagLevelOrderDFS_helper(node->right, level + 1, results);
}
}
};
```
{
"node_id": "algorithm-587f3b68dc7047d5b2445cb0c5fc50c3",
"keywords": [
"leetcode",
"对称二叉树"
],
"children": [],
"export": [
"solution.json"
],
"title": "对称二叉树"
}
\ No newline at end of file
<p>给定一个二叉树,检查它是否是镜像对称的。</p>
<p>&nbsp;</p>
<p>例如,二叉树&nbsp;<code>[1,2,2,3,4,4,3]</code> 是对称的。</p>
<pre> 1
/ \
2 2
/ \ / \
3 4 4 3
</pre>
<p>&nbsp;</p>
<p>但是下面这个&nbsp;<code>[1,2,2,null,3,null,3]</code> 则不是镜像对称的:</p>
<pre> 1
/ \
2 2
\ \
3 3
</pre>
<p>&nbsp;</p>
<p><strong>进阶:</strong></p>
<p>你可以运用递归和迭代两种方法解决这个问题吗?</p>
#include <cstddef>
#include <stack>
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution
{
public:
bool isSymmetric(TreeNode *root)
{
if (root == NULL)
return true;
TreeNode *lt = root->left, *rt = root->right;
for (std::stack<TreeNode *> stack; !stack.empty() || (lt && rt);)
{
if (lt && rt)
{
if (lt->val != rt->val)
return false;
stack.push(lt->right);
stack.push(rt->left);
lt = lt->left;
rt = rt->right;
}
else if (lt || rt)
return false;
else
{
lt = stack.top();
stack.pop();
rt = stack.top();
stack.pop();
}
}
if (lt || rt)
return false;
else
return true;
}
};
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "f1ce32e09e1e4a6baa582a6432191e67"
}
\ No newline at end of file
# 对称二叉树
<p>给定一个二叉树,检查它是否是镜像对称的。</p>
<p>&nbsp;</p>
<p>例如,二叉树&nbsp;<code>[1,2,2,3,4,4,3]</code> 是对称的。</p>
<pre> 1
/ \
2 2
/ \ / \
3 4 4 3
</pre>
<p>&nbsp;</p>
<p>但是下面这个&nbsp;<code>[1,2,2,null,3,null,3]</code> 则不是镜像对称的:</p>
<pre> 1
/ \
2 2
\ \
3 3
</pre>
<p>&nbsp;</p>
<p><strong>进阶:</strong></p>
<p>你可以运用递归和迭代两种方法解决这个问题吗?</p>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
```
### after
```cpp
```
## 答案
```cpp
class Solution
{
public:
bool isSymmetric(TreeNode *root)
{
if (!root)
return true;
queue<TreeNode *> q;
q.push(root->left);
q.push(root->right);
while (!q.empty())
{
auto p1 = q.front();
q.pop();
auto p2 = q.front();
q.pop();
if (!p1 && !p2)
continue;
if (!p1 || !p2)
return false;
if (p1->val != p2->val)
return false;
q.push(p1->right);
q.push(p1->left);
q.push(p2->right);
q.push(p2->left);
}
return true;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
bool isSymmetric(TreeNode *root)
{
queue<TreeNode *> q1, q2;
if (!root)
return true;
q1.push(root->left);
q2.push(root->right);
while (!q1.empty() && !q2.empty())
{
TreeNode *node1 = q1.front();
q1.pop();
TreeNode *node2 = q2.front();
q2.pop();
if (!node1 && !node2)
continue;
if ((!node1 && node2) || (node1 && !node2) || (node1->val != node2->val))
return false;
q1.push(node1->left);
q1.push(node1->right);
q2.push(node2->right);
q2.push(node2->left);
}
return true;
}
};
```
### B
```cpp
class Solution
{
public:
bool isSymmetric(TreeNode *root)
{
if (!root)
return true;
return helper(root->left, root->right);
}
bool helper(TreeNode *left, TreeNode *right)
{
if (!left && !right)
return true;
if ((!left && right) || (left && !right) || (left->val != right->val))
return false;
return helper(left->left, right->right) && helper(left->right, right->left);
}
};
```
### C
```cpp
class Solution
{
public:
bool isSymmetric(TreeNode *root)
{
return ismirror(root, root);
}
bool ismirror(TreeNode *t1, TreeNode *t2)
{
if (t1 == NULL && t2 == NULL)
return true;
if (t1 == NULL || t2 == NULL)
return false;
return (t1->val == t2->val) && ismirror(t1->left, t2->right) && ismirror(t1->right, t2->left);
}
};
```
{
"node_id": "algorithm-894e8b4e12a64b228b73d75b3fe22817",
"keywords": [
"leetcode",
"二叉树的层序遍历"
],
"children": [],
"export": [
"solution.json"
],
"title": "二叉树的层序遍历"
}
\ No newline at end of file
<p>给你一个二叉树,请你返回其按 <strong>层序遍历</strong> 得到的节点值。 (即逐层地,从左到右访问所有节点)。</p>
<p> </p>
<p><strong>示例:</strong><br />
二叉树:<code>[3,9,20,null,null,15,7]</code>,</p>
<pre>
3
/ \
9 20
/ \
15 7
</pre>
<p>返回其层序遍历结果:</p>
<pre>
[
[3],
[9,20],
[15,7]
]
</pre>
#include <vector>
#include <deque>
#include <cstddef>
using std::deque;
using std::vector;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution
{
public:
vector<vector<int>> levelOrder(TreeNode *root)
{
vector<vector<int>> retv;
if (root)
{
deque<TreeNode *> q{root};
while (!q.empty())
{
vector<int> v;
for (decltype(q.size()) i = 0, n = q.size(); i != n; ++i)
{
TreeNode *node = q.front();
q.pop_front();
v.push_back(node->val);
if (node->left)
q.push_back(node->left);
if (node->right)
q.push_back(node->right);
}
retv.push_back(v);
}
}
return retv;
}
};
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "9290e1345143424f8a116ab56f88f50e"
}
\ No newline at end of file
# 二叉树的层序遍历
<p>给你一个二叉树,请你返回其按 <strong>层序遍历</strong> 得到的节点值。 (即逐层地,从左到右访问所有节点)。</p>
<p> </p>
<p><strong>示例:</strong><br />
二叉树:<code>[3,9,20,null,null,15,7]</code>,</p>
<pre>
3
/ \
9 20
/ \
15 7
</pre>
<p>返回其层序遍历结果:</p>
<pre>
[
[3],
[9,20],
[15,7]
]
</pre>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
```
### after
```cpp
```
## 答案
```cpp
class Solution
{
public:
vector<vector<int>> levelOrder(TreeNode *root)
{
vector<vector<int>> res;
queue<TreeNode *> q;
if (root != NULL)
{
while (!q.empty())
{
int size = q.size();
vector<int> temp;
for (int i = 0; i < size; i++)
{
TreeNode *t = q.front();
q.pop();
temp.push_back(t->val);
if (t->left != NULL)
q.push(t->left);
if (t->right != NULL)
q.push(t->right);
}
res.push_back(temp);
temp.clear();
}
}
return res;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
vector<vector<int>> levelOrder(TreeNode *root)
{
vector<vector<int>> ret;
if (!root)
return ret;
queue<TreeNode *> q;
q.push(root);
while (!q.empty())
{
int currNodeSize = q.size();
ret.push_back(vector<int>());
for (int i = 1; i <= currNodeSize; i++)
{
TreeNode *node = q.front();
q.pop();
ret.back().push_back(node->val);
if (node->left)
q.push(node->left);
if (node->right)
q.push(node->right);
}
}
return ret;
}
};
```
### B
```cpp
class Solution
{
public:
int depth(TreeNode *root)
{
if (root == NULL)
return 0;
return max(depth(root->left), depth(root->right)) + 1;
}
void levelOrder(vector<vector<int>> &ans, TreeNode *node, int level)
{
if (!node)
return;
ans[level].push_back(node->val);
levelOrder(ans, node->left, level - 1);
levelOrder(ans, node->right, level - 1);
}
vector<vector<int>> levelOrderBottom(TreeNode *root)
{
int d = depth(root);
vector<vector<int>> ans(d, vector<int>{});
levelOrder(ans, root, d - 1);
return ans;
}
};
```
### C
```cpp
class Solution
{
public:
void dfs(TreeNode *root, vector<vector<int>> &res)
{
queue<TreeNode *> q;
q.push(root);
while (!q.empty())
{
int sz = q.size();
vector<int> tp;
while (sz > 0)
{
TreeNode *p = q.front();
q.pop();
if (p->left != NULL)
{
q.push(p->left);
}
if (p->right != NULL)
{
q.push(p->right);
}
tp.push_back(p->val);
sz--;
}
res.push_back(tp);
}
}
vector<vector<int>> levelOrder(TreeNode *root)
{
vector<vector<int>> res;
if (root == NULL)
{
return res;
}
dfs(root, res);
return res;
}
};
```
{
"node_id": "algorithm-602c74771c664b6798149723fa790697",
"keywords": [
"leetcode",
"分数到小数"
],
"children": [],
"export": [
"solution.json"
],
"title": "分数到小数"
}
\ No newline at end of file
<p>给定两个整数,分别表示分数的分子 <code>numerator</code> 和分母 <code>denominator</code>,以 <strong>字符串形式返回小数</strong></p>
<p>如果小数部分为循环小数,则将循环的部分括在括号内。</p>
<p class="MachineTrans-lang-zh-CN">如果存在多个答案,只需返回 <strong>任意一个</strong></p>
<p class="MachineTrans-lang-zh-CN">对于所有给定的输入,<strong>保证</strong> 答案字符串的长度小于 <code>10<sup>4</sup></code></p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong>numerator = 1, denominator = 2
<strong>输出:</strong>"0.5"
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong>numerator = 2, denominator = 1
<strong>输出:</strong>"2"
</pre>
<p><strong>示例 3:</strong></p>
<pre>
<strong>输入:</strong>numerator = 2, denominator = 3
<strong>输出:</strong>"0.(6)"
</pre>
<p><strong>示例 4:</strong></p>
<pre>
<strong>输入:</strong>numerator = 4, denominator = 333
<strong>输出:</strong>"0.(012)"
</pre>
<p><strong>示例 5:</strong></p>
<pre>
<strong>输入:</strong>numerator = 1, denominator = 5
<strong>输出:</strong>"0.2"
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>-2<sup>31</sup> <numerator, denominator <= 2<sup>31</sup> - 1</code></li>
<li><code>denominator != 0</code></li>
</ul>
class Solution
{
public:
string fractionToDecimal(int numerator, int denominator)
{
int m1 = numerator > 0 ? 1 : -1;
int m2 = denominator > 0 ? 1 : -1;
long long num = abs((long long)numerator);
long long den = abs((long long)denominator);
long long t = num / den;
long long res = num % den;
string ans = to_string(t);
if (m1 * m2 == -1 && (t > 0 || res > 0))
ans = '-' + ans;
if (res == 0)
return ans;
ans += '.';
unordered_map<long long, int> m;
string s = "";
int pos = 0;
while (res != 0)
{
if (m.find(res) != m.end())
{
s.insert(m[res], "(");
s += ')';
return ans + s;
}
m[res] = pos;
s += to_string((res * 10) / den);
res = (res * 10) % den;
pos++;
}
return ans + s;
}
};
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "1a7236d672a24076bcc0f1eff7050847"
}
\ No newline at end of file
# 分数到小数
<p>给定两个整数,分别表示分数的分子 <code>numerator</code> 和分母 <code>denominator</code>,以 <strong>字符串形式返回小数</strong></p>
<p>如果小数部分为循环小数,则将循环的部分括在括号内。</p>
<p class="MachineTrans-lang-zh-CN">如果存在多个答案,只需返回 <strong>任意一个</strong></p>
<p class="MachineTrans-lang-zh-CN">对于所有给定的输入,<strong>保证</strong> 答案字符串的长度小于 <code>10<sup>4</sup></code></p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong>numerator = 1, denominator = 2
<strong>输出:</strong>"0.5"
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong>numerator = 2, denominator = 1
<strong>输出:</strong>"2"
</pre>
<p><strong>示例 3:</strong></p>
<pre>
<strong>输入:</strong>numerator = 2, denominator = 3
<strong>输出:</strong>"0.(6)"
</pre>
<p><strong>示例 4:</strong></p>
<pre>
<strong>输入:</strong>numerator = 4, denominator = 333
<strong>输出:</strong>"0.(012)"
</pre>
<p><strong>示例 5:</strong></p>
<pre>
<strong>输入:</strong>numerator = 1, denominator = 5
<strong>输出:</strong>"0.2"
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>-2<sup>31</sup> <numerator, denominator <= 2<sup>31</sup> - 1</code></li>
<li><code>denominator != 0</code></li>
</ul>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
int main()
{
Solution sol;
string res;
int numerator = 1, denominator = 2;
res = sol.fractionToDecimal(numerator, denominator);
cout << res;
return 0;
}
```
## 答案
```cpp
class Solution
{
public:
const static int CACHE_SIZE = 1000;
string fractionToDecimal(int numerator, int denominator)
{
if (numerator == 0)
return "0";
bool isNegative = numerator < 0 ^ denominator < 0;
double doubleNumerator = fabs(numerator);
double doubleDenominator = fabs(denominator);
double integral = floor(doubleNumerator / doubleDenominator);
doubleNumerator -= doubleDenominator * integral;
int len = 0;
string cache;
vector<double> dividendCache;
bool isRecurring = false;
int recurringStart = 0;
int i = 0;
while (doubleNumerator)
{
doubleNumerator *= 10;
len = dividendCache.size();
for (i = 0; i < len; ++i)
if (dividendCache[i] == doubleNumerator)
{
isRecurring = true;
recurringStart = i;
break;
}
if (isRecurring)
break;
i = (int)(floor(doubleNumerator / doubleDenominator));
cache += i;
dividendCache.push_back(doubleNumerator);
doubleNumerator -= doubleDenominator * i;
}
string ret = isNegative ? "-" : "";
string tmp;
char c;
if (integral == 0)
ret += "0";
else
{
while (integral)
{
c = (int)(integral - 10 * floor(integral / 10)) + '0';
tmp = c + tmp;
integral = floor(integral / 10);
}
ret += tmp;
}
if (dividendCache.size() > 0)
ret += '.';
i = 0;
if (isRecurring)
{
ret += cache.substr(0, recurringStart);
ret += '(';
ret += cache.substr(recurringStart);
ret += ')';
}
else
ret += cache;
return ret;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
string fractionToDecimal(int numerator, int denominator)
{
typedef long long LL;
LL x = numerator, y = denominator;
if (x % y == 0)
return to_string(x / y);
string res;
if ((x < 0) ^ (y < 0))
res += '-';
x = abs(x), y = abs(y);
res += to_string(x / y) + '.';
x %= y;
unordered_map<LL, int> hash;
while (x)
{
hash[x] = res.size();
x *= 10;
res += to_string(x / y);
x %= y;
if (hash.count(x))
{
res = res.substr(0, hash[x]) + '(' + res.substr(hash[x]) + ')';
break;
}
}
return res;
}
};
```
### B
```cpp
class Solution
{
public:
string fractionToDecimal(int numerator, int denominator)
{
string ans;
unordered_map<long, int> use;
if (numerator > 0 && denominator < 0 || numerator < 0 && denominator > 0)
ans = '-';
long numerat = fabs(numerator);
long denominat = fabs(denominator);
ans += to_string(numerat / denominat);
numerat = numerat % denominat;
int point, x;
if (numerat)
{
ans += ".";
point = ans.length() - 1;
}
else
return ans;
while (numerat && use.count(numerat) == 0)
{
use[numerat] = ++point;
numerat *= 10;
x = numerat / denominat;
numerat = numerat % denominat;
ans.push_back(x + '0');
}
if (numerat)
{
ans.insert(ans.begin() + use[numerat], '(');
ans.push_back(')');
}
return ans;
}
};
```
### C
```cpp
class Solution
{
public:
string fractionToDecimal(int numerator, int denominator)
{
int m1 = numerator > 0 ? 1 : -1;
int m2 = denominator > 0 ? 1 : -1;
long long num = abs((long long)numerator);
long long den = abs((long long)denominator);
long long t = num / den;
long long res = num % den;
string ans = to_string(t);
if (m1 * m2 == -1 && (t > 0 || res > 0))
ans = '-' + ans;
if (res == 0)
return ans;
ans += '.';
unordered_map<long long, int> m;
string s = "";
int pos = 0;
while (res != 0)
{
if (m.find(res) != m.end())
{
s.insert(m[res], "(");
s += ')';
return ans + s;
}
m[res] = pos;
s += to_string((res * 10) / den);
res = (res * 10) % den;
pos++;
}
return ans + s;
}
};
```
{
"node_id": "algorithm-4458b593b07f4ee1b06db455c9f09209",
"keywords": [
"leetcode",
"单词接龙 II"
],
"children": [],
"export": [
"solution.json"
],
"title": "单词接龙 II"
}
\ No newline at end of file
<p>按字典 <code>wordList</code> 完成从单词 <code>beginWord</code> 到单词 <code>endWord</code> 转化,一个表示此过程的 <strong>转换序列</strong> 是形式上像 <code>beginWord -> s<sub>1</sub> -> s<sub>2</sub> -> ... -> s<sub>k</sub></code> 这样的单词序列,并满足:</p>
<div class="original__bRMd">
<div>
<ul>
<li>每对相邻的单词之间仅有单个字母不同。</li>
<li>转换过程中的每个单词 <code>s<sub>i</sub></code><code>1 <= i <= k</code>)必须是字典 <code>wordList</code> 中的单词。注意,<code>beginWord</code> 不必是字典 <code>wordList</code> 中的单词。</li>
<li><code>s<sub>k</sub> == endWord</code></li>
</ul>
<p>给你两个单词 <code>beginWord</code><code>endWord</code> ,以及一个字典 <code>wordList</code> 。请你找出并返回所有从 <code>beginWord</code><code>endWord</code><strong>最短转换序列</strong> ,如果不存在这样的转换序列,返回一个空列表。每个序列都应该以单词列表<em> </em><code>[beginWord, s<sub>1</sub>, s<sub>2</sub>, ..., s<sub>k</sub>]</code> 的形式返回。</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong>beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
<strong>输出:</strong>[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]
<strong>解释:</strong>存在 2 种最短的转换序列:
"hit" -> "hot" -> "dot" -> "dog" -> "cog"
"hit" -> "hot" -> "lot" -> "log" -> "cog"
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong>beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
<strong>输出:</strong>[]
<strong>解释:</strong>endWord "cog" 不在字典 wordList 中,所以不存在符合要求的转换序列。
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= beginWord.length <= 7</code></li>
<li><code>endWord.length == beginWord.length</code></li>
<li><code>1 <= wordList.length <= 5000</code></li>
<li><code>wordList[i].length == beginWord.length</code></li>
<li><code>beginWord</code><code>endWord</code><code>wordList[i]</code> 由小写英文字母组成</li>
<li><code>beginWord != endWord</code></li>
<li><code>wordList</code> 中的所有单词 <strong>互不相同</strong></li>
</ul>
</div>
</div>
class Solution
{
public:
unordered_map<string, vector<string>> tree; // 构建图
vector<vector<string>> ans; // 存放最终结果
void dfs(vector<string> &cur, string curWord, string endWord)
{
if (curWord == endWord)
{
ans.push_back(cur);
return;
}
for (string s : tree[curWord])
{
cur.push_back(s);
dfs(cur, s, endWord);
cur.pop_back();
}
}
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string> &wordList)
{
if (wordList.size() == 0 || find(wordList.begin(), wordList.end(), endWord) == wordList.end())
return {};
unordered_set<string> bfsFromBegin{beginWord}; // 自顶向下的BFS队列 !!!注意使用集合
unordered_set<string> bfsFromEnd{endWord}; // 自底向上的BFS队列 !!!注意使用集合
unordered_set<string> dirc(wordList.begin(), wordList.end()); // 初始化字典 记录未被访问过的字符串 !!!注意初始化方式
bool findFlag = false, reverseFlag = false; // findFlag两队列是否存在相同的元素 reverseflag时刻标记当前BFS遍历的方向(false为自顶向下,true为自底向上)
while (!bfsFromBegin.empty())
{
unordered_set<string> next; // 存放下一层需要遍历的节点(由于此处BFS的特殊性【一次性扩展所有节点】,所以不是直接添加到原先队列的末尾,而是借助next)
for (string s : bfsFromBegin) // 遍历过的节点从set中删除 避免成环
dirc.erase(s);
for (string s1 : bfsFromBegin)
{ // 扩展下一层的节点
for (int i = 0; i < s1.size(); ++i)
{
string s2 = s1; // s2记录由s1扩展而来字符串 !!!注意这条语句不要放错位置
for (char c = 'a'; c <= 'z'; ++c)
{
s2[i] = c;
if (dirc.count(s2) == 0)
continue;
if (bfsFromEnd.count(s2))
{
findFlag = true; // 找到双向BFS重合的字符串,BFS过程即可终止
}
else
{
next.insert(s2); // 将字符串加入扩展队列
}
reverseFlag ? tree[s2].push_back(s1) : tree[s1].push_back(s2); // 构建树 并始终保持方向从beginWord指向endWord
}
}
}
bfsFromBegin = next; // 更新队列
if (bfsFromBegin.size() > bfsFromEnd.size())
{
reverseFlag = !reverseFlag; // 取反
swap(bfsFromBegin, bfsFromEnd); // 交换BFS的队列 改变BFS的方向
}
if (findFlag)
break; // 双向BFS交汇 BFS过程终止
}
vector<string> cur = {beginWord};
dfs(cur, beginWord, endWord); // 遍历形成的树 得到起点到终点的路径
return ans;
}
};
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "84292d0d29094d59bd5be678c4c853e4"
}
\ No newline at end of file
# 单词接龙 II
<p>按字典 <code>wordList</code> 完成从单词 <code>beginWord</code> 到单词 <code>endWord</code> 转化,一个表示此过程的 <strong>转换序列</strong> 是形式上像 <code>beginWord -> s<sub>1</sub> -> s<sub>2</sub> -> ... -> s<sub>k</sub></code> 这样的单词序列,并满足:</p>
<div class="original__bRMd">
<div>
<ul>
<li>每对相邻的单词之间仅有单个字母不同。</li>
<li>转换过程中的每个单词 <code>s<sub>i</sub></code><code>1 <= i <= k</code>)必须是字典 <code>wordList</code> 中的单词。注意,<code>beginWord</code> 不必是字典 <code>wordList</code> 中的单词。</li>
<li><code>s<sub>k</sub> == endWord</code></li>
</ul>
<p>给你两个单词 <code>beginWord</code><code>endWord</code> ,以及一个字典 <code>wordList</code> 。请你找出并返回所有从 <code>beginWord</code><code>endWord</code><strong>最短转换序列</strong> ,如果不存在这样的转换序列,返回一个空列表。每个序列都应该以单词列表<em> </em><code>[beginWord, s<sub>1</sub>, s<sub>2</sub>, ..., s<sub>k</sub>]</code> 的形式返回。</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong>beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
<strong>输出:</strong>[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]
<strong>解释:</strong>存在 2 种最短的转换序列:
"hit" -> "hot" -> "dot" -> "dog" -> "cog"
"hit" -> "hot" -> "lot" -> "log" -> "cog"
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong>beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
<strong>输出:</strong>[]
<strong>解释:</strong>endWord "cog" 不在字典 wordList 中,所以不存在符合要求的转换序列。
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= beginWord.length <= 7</code></li>
<li><code>endWord.length == beginWord.length</code></li>
<li><code>1 <= wordList.length <= 5000</code></li>
<li><code>wordList[i].length == beginWord.length</code></li>
<li><code>beginWord</code><code>endWord</code><code>wordList[i]</code> 由小写英文字母组成</li>
<li><code>beginWord != endWord</code></li>
<li><code>wordList</code> 中的所有单词 <strong>互不相同</strong></li>
</ul>
</div>
</div>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
int main()
{
Solution sol;
vector<vector<string>> res;
string beginWord = "hit", endWord = "cog";
vector<string> wordList = {"hot", "dot", "dog", "lot", "log", "cog"};
res = sol.findLadders(beginWord, endWord, wordList);
for (auto i : res)
{
for (auto j : i)
cout << j << " ";
cout << endl;
}
return 0;
}
```
## 答案
```cpp
class Solution
{
public:
unordered_map<string, vector<string>> tree;
vector<vector<string>> ans;
void dfs(vector<string> &cur, string curWord, string endWord)
{
if (curWord == endWord)
{
ans.push_back(cur);
return;
}
for (string s : tree[curWord])
{
cur.push_back(s);
dfs(cur, s, endWord);
cur.pop_back();
}
}
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string> &wordList)
{
if (wordList.size() == 0 || find(wordList.begin(), wordList.end(), endWord) == wordList.end())
return {};
unordered_set<string> bfsFromBegin{beginWord};
unordered_set<string> bfsFromEnd{endWord};
unordered_set<string> dirc(wordList.begin(), wordList.end());
bool findFlag = false, reverseFlag = false;
while (!bfsFromBegin.empty())
{
unordered_set<string> next;
for (string s : bfsFromBegin)
dirc.erase(s);
for (string s1 : bfsFromBegin)
{
for (int i = 0; i < s1.size(); ++i)
{
string s2 = s1;
for (char c = 'a'; c <= 'z'; ++c)
{
s2[i] = c;
if (dirc.count(s2) == 0)
continue;
next.insert(s2);
}
reverseFlag ? tree[s2].push_back(s1) : tree[s1].push_back(s2);
}
}
bfsFromBegin = next;
if (bfsFromBegin.size() > bfsFromEnd.size())
{
reverseFlag = !reverseFlag;
swap(bfsFromBegin, bfsFromEnd);
}
if (findFlag)
break;
}
vector<string> cur = {beginWord};
dfs(cur, beginWord, endWord);
return ans;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
bool differ_one(string &s, string &t)
{
int n = 0;
for (int i = 0; i < s.size(); ++i)
if ((n += s[i] != t[i]) > 1)
return false;
return n == 1;
}
vector<vector<int>> fa;
vector<string> tmp;
vector<vector<string>> ans;
void dfs(int index, vector<string> &wordList)
{
if (fa[index].empty())
{
reverse(tmp.begin(), tmp.end());
ans.push_back(tmp);
reverse(tmp.begin(), tmp.end());
}
for (auto &x : fa[index])
{
tmp.push_back(wordList[x]);
dfs(x, wordList);
tmp.pop_back();
}
}
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string> &wordList)
{
int b = -1, e = -1, x;
for (int i = 0; i < wordList.size(); ++i)
{
if (wordList[i] == beginWord)
b = i;
if (wordList[i] == endWord)
e = i;
}
if (e == -1)
return ans;
if (b == -1)
wordList.push_back(beginWord), b = wordList.size() - 1;
queue<int> que;
fa.assign(wordList.size(), vector<int>());
vector<int> index(wordList.size(), 0);
que.push(b), index[b] = 1;
while (!que.empty())
{
x = que.front(), que.pop();
if (index[e] && index[x] >= index[e])
break;
for (int i = 0; i < wordList.size(); ++i)
if ((index[i] == 0 || index[x] + 1 == index[i]) && differ_one(wordList[x], wordList[i]))
if (index[i] == 0)
index[i] = index[x] + 1, que.push(i), fa[i].push_back(x);
else
fa[i].push_back(x);
}
if (index[e] == 0)
return ans;
tmp.push_back(endWord);
dfs(e, wordList);
tmp.pop_back();
return ans;
}
};
```
### B
```cpp
class Solution
{
public:
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string> &wordList)
{
unordered_set<string> list(wordList.begin(), wordList.end());
if (!list.count(endWord))
return {};
unordered_map<string, unordered_set<string>> trace;
unordered_set<string> p;
unordered_set<string> q{beginWord};
while (q.size() && !trace.count(endWord))
{
for (auto w : q)
{
list.erase(w);
}
p.clear();
for (auto str : q)
{
for (int i = 0; i < str.size(); ++i)
{
string tmp = str;
for (char c = 'a'; c <= 'z'; ++c)
{
tmp[i] = c;
if (list.find(tmp) == list.end())
continue;
trace[tmp].insert(str);
p.insert(tmp);
}
}
}
q = p;
}
if (!trace.size())
return {};
vector<vector<string>> res;
dfs(res, {}, trace, endWord);
return res;
}
void dfs(vector<vector<string>> &res, vector<string> path, unordered_map<string, unordered_set<string>> &trace, string &str)
{
path.push_back(str);
if (trace.count(str) == 0)
{
reverse(path.begin(), path.end());
res.push_back(path);
return;
}
for (auto word : trace[str])
dfs(res, path, trace, word);
}
};
```
### C
```cpp
class Solution
{
public:
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string> &wordList)
{
vector<vector<string>> ans;
unordered_set<string> dict(wordList.begin(), wordList.end());
vector<string> p{beginWord};
queue<vector<string>> paths;
paths.push(p);
unordered_set<string> words;
int level = 1, minlength = INT_MAX;
while (!paths.empty())
{
vector<string> t = paths.front();
paths.pop();
if (t.size() > level)
{
for (string s : words)
dict.erase(s);
words.clear();
level = t.size();
if (level > minlength)
break;
}
string last = t.back();
for (int i = 0; i < last.size(); ++i)
{
string newlast = last;
for (char ch = 'a'; ch <= 'z'; ++ch)
{
newlast[i] = ch;
if (!dict.count(newlast))
continue;
words.insert(newlast);
vector<string> nextpath = t;
nextpath.push_back(newlast);
if (newlast == endWord)
{
ans.push_back(nextpath);
minlength = level;
}
else
{
paths.push(nextpath);
}
}
}
}
return ans;
}
};
```
{
"node_id": "algorithm-6df957f509fc40d1ae8a9736bd2401dc",
"keywords": [
"leetcode",
"单词接龙"
],
"children": [],
"export": [
"solution.json"
],
"title": "单词接龙"
}
\ No newline at end of file
<p>字典 <code>wordList</code> 中从单词 <code>beginWord</code><em> </em><code>endWord</code><strong>转换序列 </strong>是一个按下述规格形成的序列:</p>
<ul>
<li>序列中第一个单词是 <code>beginWord</code></li>
<li>序列中最后一个单词是 <code>endWord</code></li>
<li>每次转换只能改变一个字母。</li>
<li>转换过程中的中间单词必须是字典 <code>wordList</code> 中的单词。</li>
</ul>
<p>给你两个单词<em> </em><code>beginWord</code><em> </em><code>endWord</code> 和一个字典 <code>wordList</code> ,找到从 <code>beginWord</code> 到 <code>endWord</code><strong>最短转换序列</strong> 中的 <strong>单词数目</strong> 。如果不存在这样的转换序列,返回 0。</p>
 
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong>beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
<strong>输出:</strong>5
<strong>解释:</strong>一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong>beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
<strong>输出:</strong>0
<strong>解释:</strong>endWord "cog" 不在字典中,所以无法进行转换。</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= beginWord.length <= 10</code></li>
<li><code>endWord.length == beginWord.length</code></li>
<li><code>1 <= wordList.length <= 5000</code></li>
<li><code>wordList[i].length == beginWord.length</code></li>
<li><code>beginWord</code><code>endWord</code><code>wordList[i]</code> 由小写英文字母组成</li>
<li><code>beginWord != endWord</code></li>
<li><code>wordList</code> 中的所有字符串 <strong>互不相同</strong></li>
</ul>
//Dijkstra算法的思路
class Solution
{
public:
int ladderLength(string beginWord, string endWord, vector<string> &wordList)
{
unordered_set<string> set(wordList.begin(), wordList.end());
if (!set.count(endWord))
return 0;
queue<pair<string, int>> q; //<字符串,该字符串到beginword的距离>
q.push({beginWord, 1});
while (!q.empty())
{
string cur = q.front().first;
int step = q.front().second;
q.pop();
if (cur == endWord)
return step;
for (int i = 0; i < cur.size(); ++i)
{
char ch = cur[i];
//遍历字母来寻找距离为1(只用改变一个字母)的单词,也即可达的单词
for (char c = 'a'; c <= 'z'; ++c)
{
if (c == ch)
continue;
cur[i] = c; //替换单个字符
if (set.count(cur))
{
q.push({cur, 1 + step});
set.erase(cur); //该节点使用过了,需要进行删除
}
}
cur[i] = ch; //复原
}
}
return 0;
}
};
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "3cee91c0e09040b7b0c46b7f5ebb7cc5"
}
\ No newline at end of file
# 单词接龙
<p>字典 <code>wordList</code> 中从单词 <code>beginWord</code><em> </em><code>endWord</code><strong>转换序列 </strong>是一个按下述规格形成的序列:</p>
<ul>
<li>序列中第一个单词是 <code>beginWord</code></li>
<li>序列中最后一个单词是 <code>endWord</code></li>
<li>每次转换只能改变一个字母。</li>
<li>转换过程中的中间单词必须是字典 <code>wordList</code> 中的单词。</li>
</ul>
<p>给你两个单词<em> </em><code>beginWord</code><em> </em><code>endWord</code> 和一个字典 <code>wordList</code> ,找到从 <code>beginWord</code> 到 <code>endWord</code><strong>最短转换序列</strong> 中的 <strong>单词数目</strong> 。如果不存在这样的转换序列,返回 0。</p>
 
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong>beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
<strong>输出:</strong>5
<strong>解释:</strong>一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong>beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
<strong>输出:</strong>0
<strong>解释:</strong>endWord "cog" 不在字典中,所以无法进行转换。</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= beginWord.length <= 10</code></li>
<li><code>endWord.length == beginWord.length</code></li>
<li><code>1 <= wordList.length <= 5000</code></li>
<li><code>wordList[i].length == beginWord.length</code></li>
<li><code>beginWord</code><code>endWord</code><code>wordList[i]</code> 由小写英文字母组成</li>
<li><code>beginWord != endWord</code></li>
<li><code>wordList</code> 中的所有字符串 <strong>互不相同</strong></li>
</ul>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
int main()
{
Solution sol;
int res;
string beginWord = "hit", endWord = "cog";
vector<string> wordList = {"hot", "dot", "dog", "lot", "log", "cog"};
res = sol.ladderLength(beginWord, endWord, wordList);
cout << res;
return 0;
}
```
## 答案
```cpp
class Solution
{
public:
int ladderLength(string beginWord, string endWord, vector<string> &wordList)
{
unordered_set<string> word;
for (auto s : wordList)
{
word.insert(s);
}
if (word.find(endWord) == word.end())
{
return 0;
}
queue<string> que;
que.push(beginWord);
unordered_set<string> visited;
visited.insert(beginWord);
int num = 1;
while (!que.empty())
{
int m = que.size();
for (int i = 0; i < m; i++)
{
string str = que.front();
que.pop();
if (str == endWord)
{
return num;
}
for (int j = 0; j < str.size(); j++)
{
string ss = str;
for (int k = 0; k < 26; k++)
{
char c = k + 'a';
if (c != str[j])
{
ss[j] = c;
}
if (visited.find(ss) == visited.end())
{
visited.insert(ss);
que.push(ss);
}
}
}
}
num++;
}
return 0;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
int ladderLength(string beginWord, string endWord, vector<string> &wordList)
{
unordered_set<string> wordSet(wordList.begin(), wordList.end());
if (!wordSet.count(endWord))
return 0;
unordered_map<string, int> pathCount{{{beginWord, 1}}};
queue<string> q{{beginWord}};
while (!q.empty())
{
string word = q.front();
q.pop();
for (int i = 0; i < word.size(); i++)
{
string newWord = word;
for (char c = 'a'; c <= 'z'; c++)
{
newWord[i] = c;
if (wordSet.count(newWord) && newWord == endWord)
return pathCount[word] + 1;
if (wordSet.count(newWord) && !pathCount.count(newWord))
{
pathCount[newWord] = pathCount[word] + 1;
q.push(newWord);
}
}
}
}
return 0;
}
};
```
### B
```cpp
class Solution
{
public:
int ladderLength(string beginWord, string endWord, vector<string> &wordList)
{
queue<string> q;
map<string, int> m1;
map<string, int> re;
int n = wordList.size();
for (int i = 0; i < n; i++)
m1[wordList[i]] = 1;
re[beginWord] = 1;
q.push(beginWord);
while ((!q.empty()) && m1.size())
{
string now = q.front();
q.pop();
int num = re[now];
int llen = now.size();
for (int i = 0; i < llen; i++)
{
string temp = now;
for (char c = 'a'; c <= 'z'; c++)
{
if (temp[i] == c)
continue;
else
temp[i] = c;
if (m1.find(temp) != m1.end())
{
if (temp == endWord)
return num + 1;
q.push(temp);
re[temp] = num + 1;
m1.erase(temp);
}
}
}
}
return 0;
}
};
```
### C
```cpp
class Solution
{
public:
int ladderLength(string beginWord, string endWord, vector<string> &wordList)
{
unordered_set<string> set(wordList.begin(), wordList.end());
if (!set.count(endWord))
return 0;
queue<pair<string, int>> q;
q.push({beginWord, 1});
while (!q.empty())
{
string cur = q.front().first;
int step = q.front().second;
q.pop();
if (cur == endWord)
return step;
for (int i = 0; i < cur.size(); ++i)
{
char ch = cur[i];
for (char c = 'a'; c <= 'z'; ++c)
{
if (c == ch)
continue;
cur[i] = c;
if (set.count(cur))
{
q.push({cur, 1 + step});
set.erase(cur);
}
}
cur[i] = ch;
}
}
return 0;
}
};
```
{
"node_id": "algorithm-78586cd84fd946a3ab3df877877a7a70",
"keywords": [
"leetcode",
"最长连续序列"
],
"children": [],
"export": [
"solution.json"
],
"title": "最长连续序列"
}
\ No newline at end of file
<p>给定一个未排序的整数数组 <code>nums</code> ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。</p>
<p>请你设计并实现时间复杂度为 <code>O(n)</code><em> </em>的算法解决此问题。</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong>nums = [100,4,200,1,3,2]
<strong>输出:</strong>4
<strong>解释:</strong>最长数字连续序列是 <code>[1, 2, 3, 4]。它的长度为 4。</code></pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong>nums = [0,3,7,2,5,8,4,6,0,1]
<strong>输出:</strong>9
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>0 <= nums.length <= 10<sup>5</sup></code></li>
<li><code>-10<sup>9</sup> <= nums[i] <= 10<sup>9</sup></code></li>
</ul>
#include <vector>
#include <unordered_map>
using std::unordered_map;
using std::vector;
class Solution
{
public:
int longestConsecutive(vector<int> &num)
{
unordered_map<int, int> map;
int max{0};
for (auto i : num)
if (!map[i])
{
map[i] = map[i + 1] + map[i - 1] + 1;
map[i - map[i - 1]] = map[i + map[i + 1]] = map[i];
max = std::max(max, map[i]);
}
return max;
}
};
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "dce3e3515a4b405e8aec92b075fac20f"
}
\ No newline at end of file
# 最长连续序列
<p>给定一个未排序的整数数组 <code>nums</code> ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。</p>
<p>请你设计并实现时间复杂度为 <code>O(n)</code><em> </em>的算法解决此问题。</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong>nums = [100,4,200,1,3,2]
<strong>输出:</strong>4
<strong>解释:</strong>最长数字连续序列是 <code>[1, 2, 3, 4]。它的长度为 4。</code></pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong>nums = [0,3,7,2,5,8,4,6,0,1]
<strong>输出:</strong>9
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>0 <= nums.length <= 10<sup>5</sup></code></li>
<li><code>-10<sup>9</sup> <= nums[i] <= 10<sup>9</sup></code></li>
</ul>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
int main()
{
Solution sol;
int res;
vector<int> vec = {0, 3, 7, 2, 5, 8, 4, 6, 0, 1};
res = sol.longestSequence(vec);
cout << res;
return 0;
}
```
## 答案
```cpp
class Solution
{
public:
int longestConsecutive(vector<int> &nums)
{
unordered_set<int> hash;
for (const int &num : nums)
{
hash.insert(num);
}
int ans = 0;
while (!hash.empty())
{
int cur = *(hash.begin());
hash.erase(cur);
int next = cur + 1, prev = cur - 1;
while (hash.count(next))
{
hash.erase(next++);
}
while (hash.count(prev))
{
hash.erase(prev--);
}
ans = max(ans, next - prev);
}
return ans;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
int longestConsecutive(vector<int> &nums)
{
unordered_map<int, int> mp;
int l = 0, r = 0, res = 0, len = 0;
for (int num : nums)
{
if (!mp[num])
{
l = mp[num - 1];
r = mp[num + 1];
len = l + r + 1;
res = max(res, len);
mp[num] = len;
mp[num - l] = len;
mp[num + r] = len;
}
}
return res;
}
};
```
### B
```cpp
class Solution
{
struct DisJointSet
{
vector<int> _id;
vector<int> _size;
int max_size;
int _count;
DisJointSet(int Num)
{
for (int i = 0; i < Num; i++)
{
_id.emplace_back(i);
_size.emplace_back(1);
}
_count = Num;
max_size = 1;
}
int find_(int p)
{
while (p != _id[p])
{
_id[p] = _id[_id[p]];
p = _id[p];
}
return p;
}
void _union(int p, int q)
{
int i = find_(p);
int j = find_(q);
if (i == j)
return;
if (_size[i] > _size[j])
{
_id[j] = i;
_size[i] += _size[j];
max_size = max(max_size, _size[i]);
}
else
{
_id[i] = j;
_size[j] += _size[i];
max_size = max(max_size, _size[j]);
}
_count--;
}
};
public:
int longestConsecutive(vector<int> &nums)
{
if (nums.size() == 0)
return 0;
DisJointSet disJointSet(nums.size());
unordered_set<int> nums_set;
unordered_map<int, int> nums_disJointSetID_map;
for (int i = 0; i < nums.size(); i++)
{
if (nums_set.find(nums[i]) != nums_set.end())
continue;
nums_set.insert(nums[i]);
nums_disJointSetID_map[nums[i]] = i;
if (nums_set.find(nums[i] - 1) != nums_set.end())
{
disJointSet._union(nums_disJointSetID_map[nums[i]], nums_disJointSetID_map[nums[i] - 1]);
}
if (nums_set.find(nums[i] + 1) != nums_set.end())
{
disJointSet._union(nums_disJointSetID_map[nums[i]], nums_disJointSetID_map[nums[i] + 1]);
}
}
return disJointSet.max_size;
}
};
```
### C
```cpp
class Solution
{
public:
int longestConsecutive(vector<int> &vec)
{
set<int> s;
for (int elem : vec)
s.insert(elem);
int longest = 0;
int cnt = 1;
for (auto e : s)
{
if (s.find(e + 1) != s.end())
{
cnt++;
}
else
{
cnt = 1;
}
longest = max(longest, cnt);
}
return longest;
}
};
```
{
"node_id": "algorithm-d221fe9f0a114efdbd615b8cba03e7fc",
"keywords": [
"leetcode",
"被围绕的区域"
],
"children": [],
"export": [
"solution.json"
],
"title": "被围绕的区域"
}
\ No newline at end of file
给你一个 <code>m x n</code> 的矩阵 <code>board</code> ,由若干字符 <code>'X'</code><code>'O'</code> ,找到所有被 <code>'X'</code> 围绕的区域,并将这些区域里所有的 <code>'O'</code><code>'X'</code> 填充。
<div class="original__bRMd">
<div>
<p> </p>
<p><strong>示例 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/02/19/xogrid.jpg" style="width: 550px; height: 237px;" />
<pre>
<strong>输入:</strong>board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
<strong>输出:</strong>[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
<strong>解释:</strong>被围绕的区间不会存在于边界上,换句话说,任何边界上的 <code>'O'</code> 都不会被填充为 <code>'X'</code>。 任何不在边界上,或不与边界上的 <code>'O'</code> 相连的 <code>'O'</code> 最终都会被填充为 <code>'X'</code>。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong>board = [["X"]]
<strong>输出:</strong>[["X"]]
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>m == board.length</code></li>
<li><code>n == board[i].length</code></li>
<li><code>1 <= m, n <= 200</code></li>
<li><code>board[i][j]</code><code>'X'</code><code>'O'</code></li>
</ul>
</div>
</div>
class Solution
{
public:
int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0}, n, m;
void dfs(int row, int col, vector<vector<char>> &board)
{
board[row][col] = 'o';
for (int i = 0; i < 4; ++i)
if (row + dx[i] >= 0 && row + dx[i] < n && col + dy[i] >= 0 && col + dy[i] < m && board[row + dx[i]][col + dy[i]] == 'O')
dfs(row + dx[i], col + dy[i], board);
}
void solve(vector<vector<char>> &board)
{
n = board.size(), m = n ? board[0].size() : 0;
if (!(m & n))
return;
for (int i = 0; i < n; ++i)
{
if (board[i][0] == 'O')
dfs(i, 0, board);
if (board[i][m - 1] == 'O')
dfs(i, m - 1, board);
}
for (int j = 0; j < m; ++j)
{
if (board[0][j] == 'O')
dfs(0, j, board);
if (board[n - 1][j] == 'O')
dfs(n - 1, j, board);
}
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (board[i][j] == 'O')
board[i][j] = 'X';
else if (board[i][j] == 'o')
board[i][j] = 'O';
}
};
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "a2608cf9adcf469d86ac1874392f6288"
}
\ No newline at end of file
# 被围绕的区域
给你一个 <code>m x n</code> 的矩阵 <code>board</code> ,由若干字符 <code>'X'</code><code>'O'</code> ,找到所有被 <code>'X'</code> 围绕的区域,并将这些区域里所有的 <code>'O'</code><code>'X'</code> 填充。
<div class="original__bRMd">
<div>
<p> </p>
<p><strong>示例 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/02/19/xogrid.jpg" style="width: 550px; height: 237px;" />
<pre>
<strong>输入:</strong>board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
<strong>输出:</strong>[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
<strong>解释:</strong>被围绕的区间不会存在于边界上,换句话说,任何边界上的 <code>'O'</code> 都不会被填充为 <code>'X'</code>。 任何不在边界上,或不与边界上的 <code>'O'</code> 相连的 <code>'O'</code> 最终都会被填充为 <code>'X'</code>。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong>board = [["X"]]
<strong>输出:</strong>[["X"]]
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>m == board.length</code></li>
<li><code>n == board[i].length</code></li>
<li><code>1 <= m, n <= 200</code></li>
<li><code>board[i][j]</code><code>'X'</code><code>'O'</code></li>
</ul>
</div>
</div>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
int main()
{
Solution sol;
vector<vector<char>> board = {{'X', 'X', 'X', 'X'}, {'X', 'O', 'O', 'X'}, {'X', 'X', 'O', 'X'}, {'X', 'O', 'X', 'X'}};
sol.solve(board);
for (auto i : board)
{
for (auto j : i)
cout << j << " ";
cout << endl;
}
return 0;
}
```
## 答案
```cpp
class Solution
{
public:
vector<vector<bool>> st;
int m, n;
void bfs(vector<vector<char>> &board, int a, int b)
{
int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
st[a][b] = true;
queue<pair<int, int>> q;
q.push(make_pair(a, b));
while (q.size())
{
pair<int, int> t = q.front();
q.pop();
for (int i = 0; i < 4; i++)
{
int x = dx[i] + t.first, y = dy[i] + t.second;
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O' && !st[x][y])
{
q.push(make_pair(x, y));
st[x][y] = true;
}
}
}
}
void solve(vector<vector<char>> &board)
{
if (!board.size())
return;
m = board.size(), n = board[0].size();
st = vector<vector<bool>>(m, vector<bool>(n, false));
for (int i = 0; i < m; i++)
{
if (board[i][0] == 'O')
bfs(board, i, 0);
if (board[i][n] == 'O')
bfs(board, i, n - 1);
}
for (int i = 0; i < n; i++)
{
if (board[0][i] == 'O')
bfs(board, 0, i);
if (board[m][i] == 'O')
bfs(board, m - 1, i);
}
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (!st[i][j])
board[i][j] = 'X';
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
int n, m;
void dfs(vector<vector<char>> &board, int x, int y)
{
if (x < 0 || y < 0 || x >= m || y >= n || board[x][y] != 'O')
return;
board[x][y] = 'A';
dfs(board, x + 1, y);
dfs(board, x, y + 1);
dfs(board, x - 1, y);
dfs(board, x, y - 1);
}
void solve(vector<vector<char>> &board)
{
m = board.size();
if (m == 0)
return;
n = board[0].size();
for (int i = 0; i < m; i++)
{
dfs(board, i, 0);
dfs(board, i, n - 1);
}
for (int i = 1; i < n - 1; i++)
{
dfs(board, 0, i);
dfs(board, m - 1, i);
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (board[i][j] == 'A')
board[i][j] = 'O';
else if (board[i][j] == 'O')
board[i][j] = 'X';
}
}
}
};
```
### B
```cpp
class Solution
{
public:
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
queue<pair<int, int>> s;
void solve(vector<vector<char>> &board)
{
int n = board.size();
if (n <= 2)
return;
int m = board[0].size();
if (m <= 2)
return;
for (int i = 0; i < m; i++)
{
if (board[0][i] == 'O')
s.push({0, i});
if (board[n - 1][i] == 'O')
s.push({n - 1, i});
}
for (int i = 1; i < n - 1; i++)
{
if (board[i][0] == 'O')
s.push({i, 0});
if (board[i][m - 1] == 'O')
s.push({i, m - 1});
}
while (!s.empty())
{
int x = s.front().first, y = s.front().second;
board[x][y] = '#';
s.pop();
for (int i = 0; i < 4; i++)
{
int mx = x + dx[i], my = y + dy[i];
if (mx < 0 || my < 0 || mx >= n || my >= m || board[mx][my] != 'O')
{
continue;
}
s.push({mx, my});
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (board[i][j] == '#')
board[i][j] = 'O';
else if (board[i][j] == 'O')
board[i][j] = 'X';
}
}
}
};
```
### C
```cpp
class Solution
{
public:
void dfs(vector<vector<char>> &board, int row, int col)
{
if (row < 0 || row >= board.size() || col < 0 || col >= board[0].size())
return;
if (board[row][col] != 'O')
return;
board[row][col] = '+';
dfs(board, row + 1, col);
dfs(board, row, col + 1);
dfs(board, row - 1, col);
dfs(board, row, col - 1);
}
void solve(vector<vector<char>> &board)
{
if (board.size() <= 1 || board[0].size() <= 2)
return;
for (int i = 0; i < board.size(); i++)
{
if (board[i][0] == 'O')
dfs(board, i, 0);
if (board[i][board[0].size() - 1] == 'O')
dfs(board, i, board[0].size() - 1);
}
for (int i = 0; i < board[0].size(); i++)
{
if (board[0][i] == 'O')
dfs(board, 0, i);
if (board[board.size() - 1][i] == 'O')
dfs(board, board.size() - 1, i);
}
for (int i = 0; i < board.size(); i++)
{
for (int j = 0; j < board[0].size(); j++)
{
if (board[i][j] == '+')
board[i][j] = 'O';
else if (board[i][j] == 'O')
board[i][j] = 'X';
}
}
}
};
```
{
"node_id": "algorithm-15e7a6d4c7da4ed682782b7b4b9761d2",
"keywords": [
"leetcode",
"路径总和"
],
"children": [],
"export": [
"solution.json"
],
"title": "路径总和"
}
\ No newline at end of file
<p>给你二叉树的根节点 <code>root</code> 和一个表示目标和的整数 <code>targetSum</code> ,判断该树中是否存在 <strong>根节点到叶子节点</strong> 的路径,这条路径上所有节点值相加等于目标和 <code>targetSum</code></p>
<p><strong>叶子节点</strong> 是指没有子节点的节点。</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/01/18/pathsum1.jpg" style="width: 500px; height: 356px;" />
<pre>
<strong>输入:</strong>root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
<strong>输出:</strong>true
</pre>
<p><strong>示例 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/01/18/pathsum2.jpg" />
<pre>
<strong>输入:</strong>root = [1,2,3], targetSum = 5
<strong>输出:</strong>false
</pre>
<p><strong>示例 3:</strong></p>
<pre>
<strong>输入:</strong>root = [1,2], targetSum = 0
<strong>输出:</strong>false
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li>树中节点的数目在范围 <code>[0, 5000]</code></li>
<li><code>-1000 <= Node.val <= 1000</code></li>
<li><code>-1000 <= targetSum <= 1000</code></li>
</ul>
#include <cstddef>
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution
{
public:
bool hasPathSum(TreeNode *root, int sum)
{
if (!root)
return false;
if (!root->left and !root->right and sum - root->val == 0)
return true;
return hasPathSum(root->left, sum - root->val) or hasPathSum(root->right, sum - root->val);
}
};
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "544c6d3b7e0d4116b27d5fdb8691a522"
}
\ No newline at end of file
# 路径总和
<p>给你二叉树的根节点 <code>root</code> 和一个表示目标和的整数 <code>targetSum</code> ,判断该树中是否存在 <strong>根节点到叶子节点</strong> 的路径,这条路径上所有节点值相加等于目标和 <code>targetSum</code></p>
<p><strong>叶子节点</strong> 是指没有子节点的节点。</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/01/18/pathsum1.jpg" style="width: 500px; height: 356px;" />
<pre>
<strong>输入:</strong>root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
<strong>输出:</strong>true
</pre>
<p><strong>示例 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/01/18/pathsum2.jpg" />
<pre>
<strong>输入:</strong>root = [1,2,3], targetSum = 5
<strong>输出:</strong>false
</pre>
<p><strong>示例 3:</strong></p>
<pre>
<strong>输入:</strong>root = [1,2], targetSum = 0
<strong>输出:</strong>false
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li>树中节点的数目在范围 <code>[0, 5000]</code></li>
<li><code>-1000 <= Node.val <= 1000</code></li>
<li><code>-1000 <= targetSum <= 1000</code></li>
</ul>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
```
### after
```cpp
```
## 答案
```cpp
其他三个都是错的
```
## 选项
### A
```cpp
class Solution
{
public:
bool hasPathSum(TreeNode *root, int sum)
{
if (root == NULL)
{
return false;
}
vector<TreeNode *> node_stack;
vector<int> sum_stack;
node_stack.push_back(root);
sum_stack.push_back(sum - root->val);
TreeNode *node;
int curr_sum;
while (!node_stack.empty())
{
node = node_stack.back();
node_stack.pop_back();
curr_sum = sum_stack.back();
sum_stack.pop_back();
if ((node->right == NULL) && (node->left == NULL) && (curr_sum == 0))
{
return true;
}
if (node->right != NULL)
{
node_stack.push_back(node->right);
sum_stack.push_back(curr_sum - node->right->val);
}
if (node->left != NULL)
{
node_stack.push_back(node->left);
sum_stack.push_back(curr_sum - node->left->val);
}
}
return false;
}
};
```
### B
```cpp
class Solution
{
public:
bool hasPathSum(TreeNode *root, int sum)
{
if (root == NULL)
return false;
stack<pair<TreeNode *, int>> s;
s.push(make_pair(root, sum));
TreeNode *node = root;
int currSum;
while (!s.empty())
{
node = s.top().first;
currSum = s.top().second;
s.pop();
if (node->left == NULL && node->right == NULL && node->val == currSum)
return true;
if (node->right)
s.push(make_pair(node->right, currSum - node->val));
if (node->left)
s.push(make_pair(node->left, currSum - node->val));
}
return false;
}
};
```
### C
```cpp
class Solution
{
public:
bool hasPathSum(TreeNode *root, int sum)
{
if (!root)
return false;
if (!root->left && !root->right && root->val == sum)
return true;
return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val);
}
};
```
{
"node_id": "algorithm-32f257cc9a114a4cb092581b3a017d74",
"keywords": [
"leetcode",
"路径总和 II"
],
"children": [],
"export": [
"solution.json"
],
"title": "路径总和 II"
}
\ No newline at end of file
<p>给你二叉树的根节点 <code>root</code> 和一个整数目标和 <code>targetSum</code> ,找出所有 <strong>从根节点到叶子节点</strong> 路径总和等于给定目标和的路径。</p>
<p><strong>叶子节点</strong> 是指没有子节点的节点。</p>
<div class="original__bRMd">
<div>
<p> </p>
<p><strong>示例 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/01/18/pathsumii1.jpg" style="width: 500px; height: 356px;" />
<pre>
<strong>输入:</strong>root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
<strong>输出:</strong>[[5,4,11,2],[5,8,4,5]]
</pre>
<p><strong>示例 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/01/18/pathsum2.jpg" style="width: 212px; height: 181px;" />
<pre>
<strong>输入:</strong>root = [1,2,3], targetSum = 5
<strong>输出:</strong>[]
</pre>
<p><strong>示例 3:</strong></p>
<pre>
<strong>输入:</strong>root = [1,2], targetSum = 0
<strong>输出:</strong>[]
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li>树中节点总数在范围 <code>[0, 5000]</code></li>
<li><code>-1000 <= Node.val <= 1000</code></li>
<li><code>-1000 <= targetSum <= 1000</code></li>
</ul>
</div>
</div>
#include <vector>
#include <cstddef>
#include <stack>
#include <algorithm>
using std::vector;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution
{
public:
vector<vector<int>> pathSum(TreeNode *root, int sum)
{
vector<vector<int>> ret;
vector<int> path;
pathSum(root, sum, path, ret);
return ret;
}
void pathSum(TreeNode *root, int sum, vector<int> &path, vector<vector<int>> &ret)
{
if (!root)
return;
path.push_back(root->val);
if (!root->left && !root->right && root->val == sum)
ret.push_back(path);
if (root->left)
pathSum(root->left, sum - root->val, path, ret);
if (root->right)
pathSum(root->right, sum - root->val, path, ret);
path.pop_back();
}
};
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "cebd88413a964aeca882afdf79cb545a"
}
\ No newline at end of file
# 路径总和 II
<p>给你二叉树的根节点 <code>root</code> 和一个整数目标和 <code>targetSum</code> ,找出所有 <strong>从根节点到叶子节点</strong> 路径总和等于给定目标和的路径。</p>
<p><strong>叶子节点</strong> 是指没有子节点的节点。</p>
<div class="original__bRMd">
<div>
<p> </p>
<p><strong>示例 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/01/18/pathsumii1.jpg" style="width: 500px; height: 356px;" />
<pre>
<strong>输入:</strong>root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
<strong>输出:</strong>[[5,4,11,2],[5,8,4,5]]
</pre>
<p><strong>示例 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/01/18/pathsum2.jpg" style="width: 212px; height: 181px;" />
<pre>
<strong>输入:</strong>root = [1,2,3], targetSum = 5
<strong>输出:</strong>[]
</pre>
<p><strong>示例 3:</strong></p>
<pre>
<strong>输入:</strong>root = [1,2], targetSum = 0
<strong>输出:</strong>[]
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li>树中节点总数在范围 <code>[0, 5000]</code></li>
<li><code>-1000 <= Node.val <= 1000</code></li>
<li><code>-1000 <= targetSum <= 1000</code></li>
</ul>
</div>
</div>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
```
### after
```cpp
```
## 答案
```cpp
class Solution
{
public:
vector<vector<int>> pathSum(TreeNode *root, int sum)
{
int pos = 0;
vector<int> path;
vector<vector<int>> result;
dfs(root, sum, pos, path, result);
return result;
}
private:
void dfs(TreeNode *root, int sum, int &pos, vector<int> &path, vector<vector<int>> &result)
{
if (root == NULL)
return;
pos += root->val;
path.push_back(root->val);
if (!root->left && !root->right && pos == sum)
result.push_back(path);
dfs(root->left, sum, pos, path, result);
dfs(root->right, sum, pos, path, result);
path.pop_back();
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
void find(TreeNode *node, vector<vector<int>> &result, vector<int> &path, int sum)
{
path.push_back(node->val);
if (node->left == NULL && node->right == NULL && sum == node->val)
{
result.push_back(path);
return;
}
if (node->left != NULL)
{
find(node->left, result, path, sum - node->val);
path.pop_back();
}
if (node->right != NULL)
{
find(node->right, result, path, sum - node->val);
path.pop_back();
}
}
vector<vector<int>> pathSum(TreeNode *root, int sum)
{
vector<vector<int>> result;
vector<int> path;
if (root == NULL)
{
return result;
}
find(root, result, path, sum);
return result;
}
};
```
### B
```cpp
class Solution
{
public:
vector<vector<int>> pathSum(TreeNode *root, int sum)
{
vector<vector<int>> res;
if (!root)
return res;
vector<int> temp;
dfs(root, res, temp, sum);
return res;
}
void dfs(TreeNode *root, vector<vector<int>> &res, vector<int> temp, int sum)
{
temp.push_back(root->val);
if (!root->left && !root->right && 0 == sum - root->val)
res.push_back(temp);
if (root->left)
dfs(root->left, res, temp, sum - root->val);
if (root->right)
dfs(root->right, res, temp, sum - root->val);
}
};
```
### C
```cpp
class Solution
{
public:
vector<vector<int>> pathSum(TreeNode *root, int targetSum)
{
DFS(root, targetSum);
return result;
}
void DFS(TreeNode *root, int targetSum)
{
if (root == nullptr)
return;
tmp_path.emplace_back(root->val);
targetSum -= root->val;
if (root->left == nullptr && root->right == nullptr && targetSum == 0)
{
result.emplace_back(tmp_path);
}
DFS(root->left, targetSum);
DFS(root->right, targetSum);
tmp_path.pop_back();
}
private:
vector<vector<int>> result;
vector<int> tmp_path;
};
```
{
"node_id": "algorithm-bfd16b54a79348af9077cc46f46e5169",
"keywords": [
"leetcode",
"二叉搜索树迭代器"
],
"children": [],
"export": [
"solution.json"
],
"title": "二叉搜索树迭代器"
}
\ No newline at end of file
实现一个二叉搜索树迭代器类<code>BSTIterator</code> ,表示一个按中序遍历二叉搜索树(BST)的迭代器:
<div class="original__bRMd">
<div>
<ul>
<li><code>BSTIterator(TreeNode root)</code> 初始化 <code>BSTIterator</code> 类的一个对象。BST 的根节点 <code>root</code> 会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。</li>
<li><code>boolean hasNext()</code> 如果向指针右侧遍历存在数字,则返回 <code>true</code> ;否则返回 <code>false</code></li>
<li><code>int next()</code>将指针向右移动,然后返回指针处的数字。</li>
</ul>
<p>注意,指针初始化为一个不存在于 BST 中的数字,所以对 <code>next()</code> 的首次调用将返回 BST 中的最小元素。</p>
</div>
</div>
<p>你可以假设 <code>next()</code> 调用总是有效的,也就是说,当调用 <code>next()</code> 时,BST 的中序遍历中至少存在一个下一个数字。</p>
<p> </p>
<p><strong>示例:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2018/12/25/bst-tree.png" style="width: 189px; height: 178px;" />
<pre>
<strong>输入</strong>
["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"]
[[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]
<strong>输出</strong>
[null, 3, 7, true, 9, true, 15, true, 20, false]
<strong>解释</strong>
BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]);
bSTIterator.next(); // 返回 3
bSTIterator.next(); // 返回 7
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 9
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 15
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 20
bSTIterator.hasNext(); // 返回 False
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li>树中节点的数目在范围 <code>[1, 10<sup>5</sup>]</code></li>
<li><code>0 <= Node.val <= 10<sup>6</sup></code></li>
<li>最多调用 <code>10<sup>5</sup></code><code>hasNext</code><code>next</code> 操作</li>
</ul>
<p> </p>
<p><strong>进阶:</strong></p>
<ul>
<li>你可以设计一个满足下述条件的解决方案吗?<code>next()</code><code>hasNext()</code> 操作均摊时间复杂度为 <code>O(1)</code> ,并使用 <code>O(h)</code> 内存。其中 <code>h</code> 是树的高度。</li>
</ul>
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class BSTIterator
{
public:
BSTIterator(TreeNode *root)
{
TreeNode *cur = root;
while (cur)
{
st.push(cur);
cur = cur->left;
}
}
/** @return whether we have a next smallest number */
bool hasNext()
{
return !st.empty();
}
/** @return the next smallest number */
int next()
{
TreeNode *next = st.top();
TreeNode *cur = next->right;
st.pop();
while (cur)
{
st.push(cur);
cur = cur->left;
}
return next->val;
}
private:
stack<TreeNode *> st;
};
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "860327443b0d4f12a8fb51c7d674c3e9"
}
\ No newline at end of file
# 二叉搜索树迭代器
实现一个二叉搜索树迭代器类<code>BSTIterator</code> ,表示一个按中序遍历二叉搜索树(BST)的迭代器:
<div class="original__bRMd">
<div>
<ul>
<li><code>BSTIterator(TreeNode root)</code> 初始化 <code>BSTIterator</code> 类的一个对象。BST 的根节点 <code>root</code> 会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。</li>
<li><code>boolean hasNext()</code> 如果向指针右侧遍历存在数字,则返回 <code>true</code> ;否则返回 <code>false</code></li>
<li><code>int next()</code>将指针向右移动,然后返回指针处的数字。</li>
</ul>
<p>注意,指针初始化为一个不存在于 BST 中的数字,所以对 <code>next()</code> 的首次调用将返回 BST 中的最小元素。</p>
</div>
</div>
<p>你可以假设 <code>next()</code> 调用总是有效的,也就是说,当调用 <code>next()</code> 时,BST 的中序遍历中至少存在一个下一个数字。</p>
<p> </p>
<p><strong>示例:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2018/12/25/bst-tree.png" style="width: 189px; height: 178px;" />
<pre>
<strong>输入</strong>
["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"]
[[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]
<strong>输出</strong>
[null, 3, 7, true, 9, true, 15, true, 20, false]
<strong>解释</strong>
BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]);
bSTIterator.next(); // 返回 3
bSTIterator.next(); // 返回 7
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 9
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 15
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 20
bSTIterator.hasNext(); // 返回 False
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li>树中节点的数目在范围 <code>[1, 10<sup>5</sup>]</code></li>
<li><code>0 <= Node.val <= 10<sup>6</sup></code></li>
<li>最多调用 <code>10<sup>5</sup></code><code>hasNext</code><code>next</code> 操作</li>
</ul>
<p> </p>
<p><strong>进阶:</strong></p>
<ul>
<li>你可以设计一个满足下述条件的解决方案吗?<code>next()</code><code>hasNext()</code> 操作均摊时间复杂度为 <code>O(1)</code> ,并使用 <code>O(h)</code> 内存。其中 <code>h</code> 是树的高度。</li>
</ul>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
```
### after
```cpp
/**
* Your BSTIterator object will be instantiated and called as such:
* BSTIterator* obj = new BSTIterator(root);
* int param_1 = obj->next();
* bool param_2 = obj->hasNext();
*/
```
## 答案
```cpp
class BSTIterator
{
private:
void traverse(TreeNode *root, vector<int> &res)
{
if (root == nullptr)
{
return;
}
traverse(root->right, res);
traverse(root->left, res);
res.push_back(root->val);
}
vector<int> inorder(TreeNode *root)
{
vector<int> res;
traverse(root, res);
return res;
}
vector<int> arr;
int idx;
public:
BSTIterator(TreeNode *root) : idx(0), arr(inorder(root))
{
}
int next()
{
return arr[idx++];
}
bool hasNext()
{
return idx < arr.size();
}
};
```
## 选项
### A
```cpp
class BSTIterator
{
private:
void inorder(TreeNode *root, vector<int> &vec)
{
if (!root)
return;
inorder(root->left, vec);
vec.emplace_back(root->val);
inorder(root->right, vec);
}
vector<int> inorderTraversal(TreeNode *root)
{
vector<int> ret;
inorder(root, ret);
return ret;
}
vector<int> buf;
size_t idx;
public:
BSTIterator(TreeNode *root)
{
idx = 0;
buf = inorderTraversal(root);
}
int next()
{
return buf[idx++];
}
bool hasNext()
{
return idx < buf.size();
}
};
```
### B
```cpp
class BSTIterator
{
public:
stack<TreeNode *> treeMin;
BSTIterator(TreeNode *root)
{
TreeNode *t = root;
while (t)
{
treeMin.push(t);
t = t->left;
}
}
/** @return the next smallest number */
int next()
{
TreeNode *tmp = treeMin.top();
int res = tmp->val;
treeMin.pop();
tmp = tmp->right;
while (tmp)
{
treeMin.push(tmp);
tmp = tmp->left;
}
return res;
}
/** @return whether we have a next smallest number */
bool hasNext()
{
if (treeMin.empty())
return false;
else
return true;
}
};
```
### C
```cpp
class BSTIterator
{
public:
queue<int> q;
BSTIterator(TreeNode *root)
{
inorder(root, q);
}
void inorder(TreeNode *root, queue<int> &q)
{
if (root == NULL)
return;
inorder(root->left, q);
q.push(root->val);
inorder(root->right, q);
}
/** @return the next smallest number */
int next()
{
int tmp = q.front();
q.pop();
return tmp;
}
/** @return whether we have a next smallest number */
bool hasNext()
{
if (q.empty())
return false;
else
return true;
}
};
```
{
"node_id": "algorithm-14d4d8e793b84c1cb3efe42497cfb78c",
"keywords": [
"leetcode",
"实现 Trie (前缀树)"
],
"children": [],
"export": [
"solution.json"
],
"title": "实现 Trie (前缀树)"
}
\ No newline at end of file
<p><strong><a href="https://baike.baidu.com/item/字典树/9825209?fr=aladdin" target="_blank">Trie</a></strong>(发音类似 "try")或者说 <strong>前缀树</strong> 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。</p>
<p>请你实现 Trie 类:</p>
<ul>
<li><code>Trie()</code> 初始化前缀树对象。</li>
<li><code>void insert(String word)</code> 向前缀树中插入字符串 <code>word</code></li>
<li><code>boolean search(String word)</code> 如果字符串 <code>word</code> 在前缀树中,返回 <code>true</code>(即,在检索之前已经插入);否则,返回 <code>false</code></li>
<li><code>boolean startsWith(String prefix)</code> 如果之前已经插入的字符串 <code>word</code> 的前缀之一为 <code>prefix</code> ,返回 <code>true</code> ;否则,返回 <code>false</code></li>
</ul>
<p> </p>
<p><strong>示例:</strong></p>
<pre>
<strong>输入</strong>
["Trie", "insert", "search", "search", "startsWith", "insert", "search"]
[[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]
<strong>输出</strong>
[null, null, true, false, true, null, true]
<strong>解释</strong>
Trie trie = new Trie();
trie.insert("apple");
trie.search("apple"); // 返回 True
trie.search("app"); // 返回 False
trie.startsWith("app"); // 返回 True
trie.insert("app");
trie.search("app"); // 返回 True
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= word.length, prefix.length <= 2000</code></li>
<li><code>word</code><code>prefix</code> 仅由小写英文字母组成</li>
<li><code>insert</code><code>search</code><code>startsWith</code> 调用次数 <strong>总计</strong> 不超过 <code>3 * 10<sup>4</sup></code></li>
</ul>
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "fc412fd05a0244d0a8cd4d86cf9e775b"
}
\ No newline at end of file
# 实现 Trie (前缀树)
<p><strong><a href="https://baike.baidu.com/item/字典树/9825209?fr=aladdin" target="_blank">Trie</a></strong>(发音类似 "try")或者说 <strong>前缀树</strong> 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。</p>
<p>请你实现 Trie 类:</p>
<ul>
<li><code>Trie()</code> 初始化前缀树对象。</li>
<li><code>void insert(String word)</code> 向前缀树中插入字符串 <code>word</code></li>
<li><code>boolean search(String word)</code> 如果字符串 <code>word</code> 在前缀树中,返回 <code>true</code>(即,在检索之前已经插入);否则,返回 <code>false</code></li>
<li><code>boolean startsWith(String prefix)</code> 如果之前已经插入的字符串 <code>word</code> 的前缀之一为 <code>prefix</code> ,返回 <code>true</code> ;否则,返回 <code>false</code></li>
</ul>
<p> </p>
<p><strong>示例:</strong></p>
<pre>
<strong>输入</strong>
["Trie", "insert", "search", "search", "startsWith", "insert", "search"]
[[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]
<strong>输出</strong>
[null, null, true, false, true, null, true]
<strong>解释</strong>
Trie trie = new Trie();
trie.insert("apple");
trie.search("apple"); // 返回 True
trie.search("app"); // 返回 False
trie.startsWith("app"); // 返回 True
trie.insert("app");
trie.search("app"); // 返回 True
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= word.length, prefix.length <= 2000</code></li>
<li><code>word</code><code>prefix</code> 仅由小写英文字母组成</li>
<li><code>insert</code><code>search</code><code>startsWith</code> 调用次数 <strong>总计</strong> 不超过 <code>3 * 10<sup>4</sup></code></li>
</ul>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
```
## 答案
```cpp
class TrieNode
{
public:
bool end_with;
TrieNode *next[26];
TrieNode()
{
end_with = false;
memset(next, 0, sizeof(next));
}
};
class Trie
{
TrieNode root;
public:
/** Initialize your data structure here. */
Trie() {}
/** Inserts a word into the trie. */
void insert(string word)
{
TrieNode *node = &root;
for (int i = 0; i < word.size(); i++)
{
int c = word[i] - 'a';
node->next[c] = new TrieNode();
node = node->next[c];
}
node->end_with = true;
}
/** Returns if the word is in the trie. */
bool search(string word)
{
TrieNode *node = &root;
for (int i = 0; i < word.size(); i++)
{
if (node->next[word[i] - 'a'] != NULL)
node = node->next[word[i] - 'a'];
else
return false;
}
return (node->end_with) ? true : false;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix)
{
TrieNode *node = &root;
for (int i = 0; i < prefix.size(); i++)
{
if (node->next[prefix[i] - 'a'] != NULL)
node = node->next[prefix[i] - 'a'];
else
return false;
}
return true;
}
};
```
## 选项
### A
```cpp
struct TrieNode
{
bool isEnd = false;
TrieNode *children[26] = {NULL};
};
class Trie
{
public:
Trie() : root(new TrieNode) {}
void insert(string word)
{
TrieNode *p = root;
for (int i = 0; i < word.size(); ++i)
{
int idx = word[i] - 'a';
if (p->children[idx] == NULL)
p->children[idx] = new TrieNode;
p = p->children[idx];
}
p->isEnd = true;
}
bool search(string word)
{
auto p = root;
for (int i = 0; i < word.size(); ++i)
{
int idx = word[i] - 'a';
if (p->children[idx] == NULL)
return false;
p = p->children[idx];
}
return p->isEnd;
}
bool startsWith(string prefix)
{
auto p = root;
for (int i = 0; i < prefix.size(); ++i)
{
int idx = prefix[i] - 'a';
if (p->children[idx] == NULL)
return false;
p = p->children[idx];
}
return true;
}
private:
TrieNode *root;
};
```
### B
```cpp
struct TrieNode
{
const static int MaxBranchNum = 26;
char data;
bool isEnd = false;
vector<TrieNode *> children = vector<TrieNode *>(26);
TrieNode(char data) : data(data){};
};
class Trie
{
public:
Trie() : root(new TrieNode('/')) {}
void insert(string word)
{
TrieNode *p = root;
for (int i = 0; i < word.size(); ++i)
{
int idx = word[i] - 'a';
if (p->children[idx] == NULL)
p->children[idx] = new TrieNode(word[i]);
p = p->children[idx];
}
p->isEnd = true;
}
bool search(string word)
{
auto p = root;
for (int i = 0; i < word.size(); ++i)
{
int idx = word[i] - 'a';
if (p->children[idx] == NULL)
return false;
p = p->children[idx];
}
return p->isEnd;
}
bool startsWith(string prefix)
{
auto p = root;
for (int i = 0; i < prefix.size(); ++i)
{
int idx = prefix[i] - 'a';
if (p->children[idx] == NULL)
return false;
p = p->children[idx];
}
return true;
}
private:
TrieNode *root;
};
```
### C
```cpp
struct Node
{
map<char, Node *> next;
bool f = false;
};
class Trie
{
public:
Node *head;
/** Initialize your data structure here. */
Trie()
{
head = new Node();
}
/** Inserts a word into the trie. */
void insert(string word)
{
Node *t = head;
for (char c : word)
{
if (t->next[c] == NULL)
{
Node *n = new Node;
t->next[c] = n;
}
t = t->next[c];
}
t->f = true;
}
/** Returns if the word is in the trie. */
bool search(string word)
{
Node *t = head;
for (char c : word)
{
if (t->next[c] == NULL)
{
return false;
}
t = t->next[c];
}
return t->f;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix)
{
Node *t = head;
for (char c : prefix)
{
if (t->next[c] == NULL)
{
return false;
}
t = t->next[c];
}
return true;
}
};
```
{
"node_id": "algorithm-c0fc6a20b2914daba094b822d884d76f",
"keywords": [
"leetcode",
"TinyURL 的加密与解密"
],
"children": [],
"export": [
"solution.json"
],
"title": "TinyURL 的加密与解密"
}
\ No newline at end of file
<p>TinyURL是一种URL简化服务, 比如:当你输入一个URL&nbsp;<code>https://leetcode.com/problems/design-tinyurl</code>&nbsp;时,它将返回一个简化的URL&nbsp;<code>http://tinyurl.com/4e9iAk</code>.</p>
<p>要求:设计一个 TinyURL 的加密&nbsp;<code>encode</code>&nbsp;和解密&nbsp;<code>decode</code>&nbsp;的方法。你的加密和解密算法如何设计和运作是没有限制的,你只需要保证一个URL可以被加密成一个TinyURL,并且这个TinyURL可以用解密方法恢复成原本的URL。</p>
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "4bb1610f42434348b3ea6b82290f04d3"
}
\ No newline at end of file
# TinyURL 的加密与解密
<p>TinyURL是一种URL简化服务, 比如:当你输入一个URL&nbsp;<code>https://leetcode.com/problems/design-tinyurl</code>&nbsp;时,它将返回一个简化的URL&nbsp;<code>http://tinyurl.com/4e9iAk</code>.</p>
<p>要求:设计一个 TinyURL 的加密&nbsp;<code>encode</code>&nbsp;和解密&nbsp;<code>decode</code>&nbsp;的方法。你的加密和解密算法如何设计和运作是没有限制的,你只需要保证一个URL可以被加密成一个TinyURL,并且这个TinyURL可以用解密方法恢复成原本的URL。</p>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
// Your Solution object will be instantiated and called as such:
// Solution solution;
// solution.decode(solution.encode(url));
```
## 答案
```cpp
class Solution
{
public:
map<string, string> mp;
string encode(string longUrl)
{
string str = "tinyurl" + to_string(key);
mp[str] = longUrl;
return str;
}
string decode(string shortUrl)
{
return mp[shortUrl];
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
unordered_map<string, string> hashMap;
string TINYURL_PREFIX = "http://tinyurl.com/";
string INDEX = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
string encode(string longUrl)
{
string newShortStr = "";
while (true)
{
for (int i = 0; i < 6; ++i)
{
newShortStr += INDEX[rand() % 62];
}
string resStr = TINYURL_PREFIX + newShortStr;
if (hashMap.count(resStr) == 0)
{
hashMap[resStr] = longUrl;
return resStr;
}
}
}
string decode(string shortUrl)
{
return hashMap[shortUrl];
}
};
```
### B
```cpp
class Solution
{
public:
using ull = unsigned long long;
const ull base = 11;
const string code = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const ull len = code.size();
unordered_map<string, string> m;
ull hashCode(string url)
{
ull hash = 0;
for (auto c : url)
{
hash *= base;
hash += c;
}
return hash;
}
string hashToString(ull n)
{
string ans;
while (n)
{
ans += code[n % len];
n /= len;
}
return ans;
}
string encode(string longUrl)
{
string shortUrl = hashToString(hashCode(longUrl));
m[shortUrl] = longUrl;
return shortUrl;
}
string decode(string shortUrl)
{
return m[shortUrl];
}
};
```
### C
```cpp
class Solution
{
public:
unordered_map<string, string> mp;
int i = 0;
string encode(string longUrl)
{
mp[to_string(i)] = longUrl;
string res = "http://tinyurl.com/" + to_string(i++);
return res;
}
string decode(string shortUrl)
{
return mp[shortUrl.substr(19, shortUrl.size() - 19)];
}
};
```
{
"node_id": "algorithm-877445164cb3460c98afa991e4cba2d9",
"keywords": [
"leetcode",
"按要求补齐数组"
],
"children": [],
"export": [
"solution.json"
],
"title": "按要求补齐数组"
}
\ No newline at end of file
<p>给定一个已排序的正整数数组 <em>nums,</em>和一个正整数&nbsp;<em>n 。</em>&nbsp;<code>[1, n]</code>&nbsp;区间内选取任意个数字补充到&nbsp;<em>nums&nbsp;</em>中,使得&nbsp;<code>[1, n]</code>&nbsp;区间内的任何数字都可以用&nbsp;<em>nums&nbsp;</em>中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。</p>
<p><strong>示例&nbsp;1:</strong></p>
<pre><strong>输入: </strong><em>nums</em> = <code>[1,3]</code>, <em>n</em> = <code>6</code>
<strong>输出: </strong>1
<strong>解释:</strong>
根据<em> nums&nbsp;</em>里现有的组合&nbsp;<code>[1], [3], [1,3]</code>,可以得出&nbsp;<code>1, 3, 4</code>
现在如果我们将&nbsp;<code>2</code>&nbsp;添加到&nbsp;<em>nums 中,</em>&nbsp;组合变为: <code>[1], [2], [3], [1,3], [2,3], [1,2,3]</code>
其和可以表示数字&nbsp;<code>1, 2, 3, 4, 5, 6</code>,能够覆盖&nbsp;<code>[1, 6]</code>&nbsp;区间里所有的数。
所以我们最少需要添加一个数字。</pre>
<p><strong>示例 2:</strong></p>
<pre><strong>输入: </strong><em>nums</em> = <code>[1,5,10]</code>, <em>n</em> = <code>20</code>
<strong>输出:</strong> 2
<strong>解释: </strong>我们需要添加&nbsp;<code>[2, 4]</code>
</pre>
<p><strong>示例&nbsp;3:</strong></p>
<pre><strong>输入: </strong><em>nums</em> = <code>[1,2,2]</code>, <em>n</em> = <code>5</code>
<strong>输出:</strong> 0
</pre>
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "f2e948669b074e0894d025effeeddcb7"
}
\ No newline at end of file
# 按要求补齐数组
<p>给定一个已排序的正整数数组 <em>nums,</em>和一个正整数&nbsp;<em>n 。</em>&nbsp;<code>[1, n]</code>&nbsp;区间内选取任意个数字补充到&nbsp;<em>nums&nbsp;</em>中,使得&nbsp;<code>[1, n]</code>&nbsp;区间内的任何数字都可以用&nbsp;<em>nums&nbsp;</em>中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。</p>
<p><strong>示例&nbsp;1:</strong></p>
<pre><strong>输入: </strong><em>nums</em> = <code>[1,3]</code>, <em>n</em> = <code>6</code>
<strong>输出: </strong>1
<strong>解释:</strong>
根据<em> nums&nbsp;</em>里现有的组合&nbsp;<code>[1], [3], [1,3]</code>,可以得出&nbsp;<code>1, 3, 4</code>
现在如果我们将&nbsp;<code>2</code>&nbsp;添加到&nbsp;<em>nums 中,</em>&nbsp;组合变为: <code>[1], [2], [3], [1,3], [2,3], [1,2,3]</code>
其和可以表示数字&nbsp;<code>1, 2, 3, 4, 5, 6</code>,能够覆盖&nbsp;<code>[1, 6]</code>&nbsp;区间里所有的数。
所以我们最少需要添加一个数字。</pre>
<p><strong>示例 2:</strong></p>
<pre><strong>输入: </strong><em>nums</em> = <code>[1,5,10]</code>, <em>n</em> = <code>20</code>
<strong>输出:</strong> 2
<strong>解释: </strong>我们需要添加&nbsp;<code>[2, 4]</code>
</pre>
<p><strong>示例&nbsp;3:</strong></p>
<pre><strong>输入: </strong><em>nums</em> = <code>[1,2,2]</code>, <em>n</em> = <code>5</code>
<strong>输出:</strong> 0
</pre>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
int main()
{
Solution sol;
vector<int> nums = {1, 5, 10};
int n = 20;
int res = sol.minPatches(nums, n);
cout << res;
return 0;
}
```
## 答案
```cpp
class Solution
{
public:
int minPatches(vector<int> &nums, int n)
{
long sum = 0;
int reti = 0;
int i = 0;
while (sum < n)
{
if (i >= nums.size())
break;
if ((sum + 1) >= nums[i])
{
sum += nums[++i];
}
else
{
int temp = sum + 1;
sum += temp;
reti++;
}
}
while (sum < n)
{
int temp = sum + 1;
sum += temp;
}
return reti;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
int minPatches(vector<int> &nums, int n)
{
int resultCnt = 0;
int numsSize = nums.size(), index = 0;
long long head = 1;
while (head <= n)
{
if (index < numsSize && nums[index] <= head)
{
head += nums[index++];
}
else
{
head += head;
resultCnt += 1;
}
}
return resultCnt;
}
};
```
### B
```cpp
class Solution
{
public:
int minPatches(vector<int> &nums, int n)
{
int patchCount = 0, i = 0;
long miss = 1;
while (miss <= n)
{
if (i < nums.size() && miss >= nums[i])
miss += nums[i++];
else
{
patchCount++;
miss = miss * 2;
}
}
return patchCount;
}
};
```
### C
```cpp
class Solution
{
public:
int minPatches(vector<int> &nums, int n)
{
int len = nums.size(), i = 0;
long current_coverage = 0;
int ans = 0;
while (current_coverage < n)
{
if (i < len)
{
if (nums[i] <= current_coverage + 1)
{
current_coverage += nums[i];
i++;
}
else
{
ans++;
current_coverage += current_coverage + 1;
}
}
else
{
ans++;
current_coverage += current_coverage + 1;
}
}
return ans;
}
};
```
{
"node_id": "algorithm-79927151f5264497aa7cf4054ca7c573",
"keywords": [
"leetcode",
"最大数"
],
"children": [],
"export": [
"solution.json"
],
"title": "最大数"
}
\ No newline at end of file
<p>给定一组非负整数 <code>nums</code>,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。</p>
<p><strong>注意:</strong>输出结果可能非常大,所以你需要返回一个字符串而不是整数。</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入<code></code></strong><code>nums = [10,2]</code>
<strong>输出:</strong><code>"210"</code></pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入<code></code></strong><code>nums = [3,30,34,5,9]</code>
<strong>输出:</strong><code>"9534330"</code>
</pre>
<p><strong>示例 3:</strong></p>
<pre>
<strong>输入<code></code></strong>nums = [1]
<strong>输出:</strong>"1"
</pre>
<p><strong>示例 4:</strong></p>
<pre>
<strong>输入<code></code></strong>nums = [10]
<strong>输出:</strong>"10"
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= nums.length <= 100</code></li>
<li><code>0 <= nums[i] <= 10<sup>9</sup></code></li>
</ul>
class Solution
{
public:
bool static cmp(string a, string b)
{
return (a + b) > (b + a); //当a+b>b+a时a排在b前面
}
string largestNumber(vector<int> &nums)
{
int flag = 0;
vector<string> v;
for (vector<int>::iterator i = nums.begin(); i < nums.end(); i++)
{
v.push_back(to_string(*i));
if (*i)
flag = 1;
}
if (!flag)
return "0";
sort(v.begin(), v.end(), cmp); //没有生成实例就要调用,故cmp应声明为static
string s = "";
for (int i = 0; i < v.size(); i++)
s = s + v[i];
return s;
}
};
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "8ffe9f362cee4808887feae6a1a4baab"
}
\ No newline at end of file
# 最大数
<p>给定一组非负整数 <code>nums</code>,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。</p>
<p><strong>注意:</strong>输出结果可能非常大,所以你需要返回一个字符串而不是整数。</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入<code></code></strong><code>nums = [10,2]</code>
<strong>输出:</strong><code>"210"</code></pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入<code></code></strong><code>nums = [3,30,34,5,9]</code>
<strong>输出:</strong><code>"9534330"</code>
</pre>
<p><strong>示例 3:</strong></p>
<pre>
<strong>输入<code></code></strong>nums = [1]
<strong>输出:</strong>"1"
</pre>
<p><strong>示例 4:</strong></p>
<pre>
<strong>输入<code></code></strong>nums = [10]
<strong>输出:</strong>"10"
</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= nums.length <= 100</code></li>
<li><code>0 <= nums[i] <= 10<sup>9</sup></code></li>
</ul>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
int main()
{
Solution sol;
vector<int> nums = {3, 30, 34, 5, 9};
string res = sol.largestNumber(nums);
cout << res;
return 0;
}
```
## 答案
```cpp
class Solution
{
public:
string largestNumber(vector<int> &nums)
{
string ans;
for (int i = 0; i < nums.size(); i++)
{
for (int j = nums.size() - 1; j > i; j--)
{
if (to_string(nums[j - 1]) + to_string(nums[j]) > to_string(nums[j]) + to_string(nums[j - 1]))
{
int tmp = nums[j - 1];
nums[j - 1] = nums[j];
nums[j] = tmp;
}
}
ans += to_string(nums[i]);
}
if (ans + "0" == "0" + ans)
return "0";
return ans;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
string largestNumber(vector<int> &nums)
{
string ans;
sort(nums.begin(), nums.end(), [](int a, int b)
{ return to_string(a) + to_string(b) > to_string(b) + to_string(a); });
for (auto it : nums)
{
ans += to_string(it);
}
return ans[0] == '0' ? "0" : ans;
}
};
```
### B
```cpp
class Solution
{
public:
string largestNumber(vector<int> &nums)
{
if (*max_element(nums.begin(), nums.end()) == 0)
return to_string(0);
vector<string> vec(nums.size());
for (int i = 0; i < nums.size(); ++i)
vec[i] = to_string(nums[i]);
sort(vec.begin(), vec.end(), [](const string &s1, const string &s2)
{ return s1 + s2 > s2 + s1; });
return accumulate(vec.begin(), vec.end(), string());
}
};
```
### C
```cpp
class Solution
{
public:
string largestNumber(vector<int> &nums)
{
string res = "";
int n = nums.size();
vector<string> tmp;
for (int i = 0; i < n; i++)
{
tmp.push_back(to_string(nums[i]));
}
sort(tmp.begin(), tmp.end(), compare);
for (int i = 0; i < tmp.size(); i++)
{
res += tmp[i];
}
if ('0' == res[0])
{
return "0";
}
else
{
return res;
}
}
};
```
{
"node_id": "algorithm-b19a2b60d98244eb9e56813921864871",
"keywords": [
"leetcode",
"去除重复字母"
],
"children": [],
"export": [
"solution.json"
],
"title": "去除重复字母"
}
\ No newline at end of file
<p>给你一个字符串 <code>s</code> ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 <strong>返回结果的字典序最小</strong>(要求不能打乱其他字符的相对位置)。</p>
<p><strong>注意:</strong>该题与 1081 <a href="https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters">https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters</a> 相同</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong><code>s = "bcabc"</code>
<strong>输出<code></code></strong><code>"abc"</code>
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong><code>s = "cbacdcbc"</code>
<strong>输出:</strong><code>"acdb"</code></pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= s.length <= 10<sup>4</sup></code></li>
<li><code>s</code> 由小写英文字母组成</li>
</ul>
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "17a3169f78f74c65ae53df020a642995"
}
\ No newline at end of file
# 去除重复字母
<p>给你一个字符串 <code>s</code> ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 <strong>返回结果的字典序最小</strong>(要求不能打乱其他字符的相对位置)。</p>
<p><strong>注意:</strong>该题与 1081 <a href="https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters">https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters</a> 相同</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong><code>s = "bcabc"</code>
<strong>输出<code></code></strong><code>"abc"</code>
</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong><code>s = "cbacdcbc"</code>
<strong>输出:</strong><code>"acdb"</code></pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= s.length <= 10<sup>4</sup></code></li>
<li><code>s</code> 由小写英文字母组成</li>
</ul>
<p>以下错误的选项是?</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
int main()
{
Solution sol;
string s = "cbacdcbc";
string res = sol.removeDuplicateLetters(s);
cout << res;
return 0;
}
```
## 答案
```cpp
class Solution
{
public:
string removeDuplicateLetters(string s)
{
int count[26] = {0};
for (int i = 0; i < s.length(); i++)
count[s[i] - 'a']++;
int pos = 0;
for (int i = 0; i < s.length(); i++)
{
if (s[i] < s[pos])
pos = i;
if (count[s[i] - 'a'] == 0)
break;
}
string suffix;
if (pos + 1 > s.length())
suffix = "";
else
suffix = s.substr(pos + 1, s.length() - pos - 1);
return s.length() == 0 ? "" : s[pos] + removeDuplicateLetters(removeOneLetter(suffix, s[pos]));
}
string removeOneLetter(string s, char ch)
{
while (1)
{
int index = s.find(ch);
if (index != -1)
s = s.erase(index, 1);
else
break;
}
return s;
}
};
```
## 选项
### A
```cpp
class Solution
{
public:
string removeDuplicateLetters(string s)
{
unordered_map<char, int> mp;
unordered_map<char, bool> isIn;
int len = s.length();
for (int i = 0; i < len; i++)
{
mp[s[i]]++;
isIn[s[i]] = false;
}
stack<char> ans;
for (int i = 0; i < len; i++)
{
if (ans.empty())
{
ans.push(s[i]);
isIn[s[i]] = true;
}
else if (!isIn[s[i]])
{
while (!ans.empty() && s[i] < ans.top())
{
if (mp[ans.top()])
{
isIn[ans.top()] = false;
ans.pop();
}
else
break;
}
ans.push(s[i]);
isIn[s[i]] = true;
}
mp[s[i]]--;
}
string ansS;
while (!ans.empty())
{
ansS += ans.top();
ans.pop();
}
reverse(ansS.begin(), ansS.end());
return ansS;
}
};
```
### B
```cpp
class Solution
{
public:
string removeDuplicateLetters(string s)
{
string ans;
for (int i = 0; i < s.size(); i++)
{
if (ans.find(s[i]) != string::npos)
continue;
for (int j = ans.length() - 1; j >= 0; j--)
{
if (ans[j] > s[i] && s.find(ans[j], i + 1) != string::npos)
{
ans.erase(j);
continue;
}
break;
}
ans += s[i];
}
return ans;
}
};
```
### C
```cpp
class Solution
{
public:
string res = "0";
string removeDuplicateLetters(string s)
{
int count[26] = {0};
int visited[26] = {0};
for (int i = 0; i < s.size(); ++i)
++count[s[i] - 'a'];
for (const auto &c : s)
{
--count[c - 'a'];
if (visited[c - 'a'] == 1)
continue;
while (c < res.back() && count[res.back() - 'a'])
{
visited[res.back() - 'a'] = 0;
res.pop_back();
}
res += c;
visited[c - 'a'] = 1;
}
return res.substr(1);
}
};
```
{
"node_id": "algorithm-476b83ac859c40f3a6efd6c3632f1ad2",
"keywords": [
"leetcode",
"拼接最大数"
],
"children": [],
"export": [
"solution.json"
],
"title": "拼接最大数"
}
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "d4bef81d1bd84c0db36d6488b1932479"
}
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "c5fd58daecf5409e85df121fe9e7110b"
}
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "30dc3fe246f543ec9f26f44b0051cab1"
}
\ No newline at end of file
{
"type": "code_options",
"author": "CSDN.net",
"source": "solution.md",
"exercise_id": "7026e2bc9ba945ecb75693f21ee96a59"
}
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册