题目地址:
https://leetcode.com/problems/number-of-atoms/
给定一个化学式,以长 n n n的字符串形式给出。化学式的格式是这样的:元素都以大写字母开始,或者就是单独一个大写字母,或者是大写字母跟着若干小写字母;元素的后面可能会跟数字,表示这个元素的原子有多少个,如果不跟数字表示只有 1 1 1个;可能会含括号,括号里也是个化学式,括号后面也会跟数字,表示这整个括号里的每个元素的个数会再乘以这个数字(当然如果不跟数字就表示只有 1 1 1倍)。要求返回一个字符串,其格式是元素 + 其个数这样排列下去,个数是 1 1 1的话则不显示,元素要按照其元素名的字典序排序。
可以用栈。开个存哈希表的栈,每次进入括号的时候,就开一个新的哈希表入栈,该哈希表就存当前括号里的元素及个数;遇到右括号的时候,算一下括号里的元素个数要乘的系数,然后pop掉栈顶,这个pop出来的哈希表就存的是括号里的元素个数,将这些个数乘以系数累加到当前栈顶的哈希表里。代码如下:
class Solution {
public:
string countOfAtoms(string s) {
stack<unordered_map<string, int>> stk;
stk.push({{}});
for (int i = 0; i < s.size(); i++) {
if (s[i] == '(') stk.push({{}});
else if (s[i] == ')') {
int j = ++i;
while (j < s.size() && isdigit(s[j])) j++;
int cnt = j > i ? stoi(s.substr(i, j - i)) : 1;
auto mp = stk.top();
stk.pop();
for (auto &[k, v] : mp) stk.top()[k] += cnt * v;
i = j - 1;
} else {
int j = i + 1;
while (j < s.size() && islower(s[j])) j++;
string elem = s.substr(i, j - i);
i = j;
while (j < s.size() && isdigit(s[j])) j++;
int cnt = j > i ? stoi(s.substr(i, j - i)) : 1;
stk.top()[elem] += cnt;
i = j - 1;
}
}
string res;
map<string, int> mp(stk.top().begin(), stk.top().end());
for (auto &[k, v] : mp) {
res += k;
if (v > 1) res += to_string(v);
}
return res;
}
};
时间复杂度 O ( n 2 ) O(n^2) O(n2)(主要看括号层数是不是特别多,如果不太多的话时间大致是 O ( n ) O(n) O(n)的),空间 O ( n ) O(n) O(n)。