第726题被归类于栈下,主要难点在于括号的处理,我采取的思路是将左括号压栈,然后遇到右括号弹如临时栈,在从临时栈弹回来,弹回来时乘以右括号下的系数。
代码如下(C++)
class Solution {
public:
string countOfAtoms(string formula) {
deque<string> atoms;
deque<int> nums;
for (int i = 0; i < formula.size(); i++) {
if (formula[i] == '(')
atoms.push_back("(");
else if (formula[i] == ')') {
if (formula[i + 1] <= '9'&&formula[i + 1] >= '0') {
int num = 0;
while (formula[i + 1] <= '9'&&formula[i + 1] >= '0') {
num = num * 10 + formula[i + 1] - '0';
i++;
}
deque<string> tempatoms;
deque<int> tempnums;
while (atoms.back() != "(") {
tempatoms.push_back(atoms.back());
tempnums.push_back(nums.back());
atoms.pop_back();
nums.pop_back();
}
atoms.pop_back();
while (!tempatoms.empty()) {
atoms.push_back(tempatoms.back());
nums.push_back(tempnums.back()*num);
tempatoms.pop_back();
tempnums.pop_back();
}
}
}
else if(formula[i]>='A'&&formula[i]<='Z'){
string atom;
atom += formula[i];
while (formula[i + 1] <= 'z'&&formula[i+1] >= 'a') {
atom += formula[i + 1];
i++;
}
atoms.push_back(atom);
if (formula[i + 1] <= '9'&&formula[i + 1] >= '0') {
int num = 0;
while (formula[i + 1] <= '9'&&formula[i + 1] >= '0') {
num = num * 10 + formula[i + 1] - '0';
i++;
}
nums.push_back(num);
}
else {
nums.push_back(1);
}
}
}
map<string, int> total;
while (!atoms.empty()) {
string atom = atoms.back();
int num = nums.back();
if (total.find(atom) != total.end())
total[atom] += num;
else
total.insert({ atom,num });
atoms.pop_back();
nums.pop_back();
}
string res = "";
for (auto iter = total.begin(); iter != total.end(); iter++) {
if (iter->second == 1) {
res += iter->first;
}
else {
res += iter->first;
int num = iter->second;
string stringnum = "";
while (num != 0) {
stringnum += (num % 10 + '0');
num = num / 10;
}
for (int i = 0; i < stringnum.size(); i++) {
res += stringnum[stringnum.size()- 1 - i];
}
}
}
return res;
}
};
————————————————————————————————————————————————————————————贴一段PKU大佬的代码:http://storypku.com/2017/11/leetcode-question-726-number-of-atoms/
class Solution {
public:
string countOfAtoms(string formula) {
int n = formula.size();
std::map<string, int> stats;
std::reverse(formula.begin(), formula.end());
compute(formula, stats);
string result;
for (auto& kv : stats) {
result += kv.first;
if (kv.second > 1) {
result += std::to_string(kv.second);
}
}
return result;
}
private: // K4(ON(SO3)2)2
void compute(string& formula, std::map<string, int>& stats) {
int n = formula.size();
std::stack<int> stk; // factor
stk.push(1);
string elem; // chemical element, e.g., C, N, O, Na, Mg, Al, etc.
int factor = 1; // number of this element, default to 1 if not otherwise specified
for (int i = 0; i < n; ++i) {
auto& c = formula[i];
if (isdigit(c)) { // E.g., original 312 was reverse to 213.
int val = 0, expo = 1;
do {
val += (c - '0') * expo;
++i; expo *= 10;
} while (isdigit(c = formula[i]));
factor = val; // explicit number of this element
i -= 1;
} else if (c == ')') {
stk.push(factor * stk.top());
factor = 1; // Al(OH)3
} else if (c >= 'A' && c <= 'Z') {
elem += c;
std::reverse(elem.begin(), elem.end());
stats[elem] += factor * stk.top();
factor = 1;
elem.clear();
} else if (c >= 'a' && c <= 'z') {
elem += c;
} else { // (c == '(') {
stk.pop(); // Ca(OH)2
}
}
}
};
首先将atoms字符串反转
K4(ON(SO3)2)22)2)3OS(NO(4K
利用大写字母作为结束标志,相对于原串更容易处理,厉害了