440. 字典序的第K小数字
原题
- 建模(10叉树的前序遍历)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200619210310672.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JlQnVCdQ==,size_16,color_FFFFFF,t_70)
- 即
0 1 10 11 12 13 2 3 4 5 6 7 8 9
(从1开始,去掉0) - 流程:
- 其实只需要按层节点个数计算即可,图中节点1和节点2在第二层,因为n = 13,节点1可以移动到节点2(同一层)所以在第二层需要移动1步。
- 第三层,移动个数就是 (13 - 10 + 1) = 4 (min(13 + 1, 20) - 10)所以节点1到节点2需要移动 1 + 4 = 5 步
- 当移动步数小于等于k,说明需要向右节点移动,图中就是节点1移动到节点2
- 当移动步数大于k,说明目标值在节点1和节点2之间,我们要向下移动!即从节点1移动到节点10。
class Solution {
public:
int cal_steps(long int n, long int n1, long int n2) {
int step = 0;
while (n1 <= n) {
step += min(n2, n + 1) - n1;
n1 *= 10;
n2 *= 10;
}
return step;
}
int findKthNumber(int n, int k) {
int cur = 1;
k -= 1;
while (k > 0) {
int steps = cal_steps(n, cur, cur + 1);
if (steps <= k) {
k -= steps;
cur += 1;
} else {
k -= 1;
cur *= 10;
}
}
return cur;
}
};
726. 原子的数量
原题
DFS
class Solution {
public:
string countOfAtoms(string formula) {
int pos = 0;
string res = "";
map<string, int> m = parse(formula, pos);
for (auto& x : m) {
res += x.first + (x.second == 1 ? "" : to_string(x.second));
}
return res;
}
map<string, int> parse(string& x, int& pos) {
map<string, int> m;
while (pos < x.size()) {
if (x[pos] == '(') {
pos++;
for (auto& a : parse(x, pos))
m[a.first] += a.second;
} else if (x[pos] == ')') {
int i = ++pos;
while (pos < x.size() && isdigit(x[pos])) ++pos;
int multi = stoi(x.substr(i, pos - i));
for (auto& a : m) m[a.first] *= multi;
return m;
} else {
int i = pos++;
while (pos < x.size() && islower(x[pos])) ++pos;
string elem = x.substr(i, pos - i); i = pos;
while (pos < x.size() && isdigit(x[pos])) ++pos;
string cnt = x.substr(i, pos - i);
m[elem] += cnt.empty() ? 1 : stoi(cnt);
}
}
return m;
}
};
Stack
- 使用栈来代替递归函数,本身之上基本没有任何区别
std::move(t)
:用来表明对象t是可以moved from的,它允许高效的从t资源转换到lvalue上
class Solution {
public:
string countOfAtoms(string formula) {
string res = "";
int pos = 0;
map<string, int> cur;
stack<map<string, int>> st;
int N = formula.size();
while (pos < N) {
if (formula[pos] == '(') {
pos++;
st.push(move(cur));
} else if (formula[pos] == ')') {
int i = ++pos;
while (pos < N && isdigit(formula[pos])) ++pos;
int multi = stoi(formula.substr(i, pos - i));
for (auto& a : cur) st.top()[a.first] += a.second * multi;
cur = move(st.top());
st.pop();
} else {
int i = pos++;
while (pos < N && islower(formula[pos])) ++pos;
string elem = formula.substr(i, pos - i);
i = pos;
while (pos < N && isdigit(formula[pos])) ++pos;
string cnt = formula.substr(i, pos - i);
cur[elem] += cnt.empty() ? 1 : stoi(cnt);
}
}
for (auto& a : cur) {
res += a.first + (a.second == 1 ? "" : to_string(a.second));
}
return res;
}
};
1188. 设计有限阻塞队列
参考
199. 二叉树的右视图
参考
BFS
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
if (!root) return {};
queue<TreeNode*> q;
q.push(root);
vector<int> res;
while (!q.empty()) {
res.push_back(q.front()->val);
int sz = q.size();
for (int i = 0; i < sz; i++) {
auto x = q.front(); q.pop();
if (x->right) q.push(x->right);
if (x->left) q.push(x->left);
}
}
return res;
}
};
DFS
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
int depth = 0;
vector<int> res;
dfs(root, res, depth);
return res;
}
void dfs(TreeNode* root, vector<int>& res, int dep) {
if (!root) return;
if (res.size() == dep) res.push_back(root->val);
dfs(root->right, res, dep+1);
dfs(root->left, res, dep+1);
}
};
135. 分发糖果
参考