LeetCode-726 原子的数量 递归

LeetCode-726 原子的数量 递归

题目链接:LeetCode-726 原子的数量

给你一个字符串化学式 formula ,返回 每种原子的数量 。

原子总是以一个大写字母开始,接着跟随 0 个或任意个小写字母,表示原子的名字。

如果数量大于 1,原子后会跟着数字表示原子的数量。如果数量等于 1 则不会跟数字。

例如,“H2O” 和 “H2O2” 是可行的,但 “H1O2” 这个表达是不可行的。
两个化学式连在一起可以构成新的化学式。

例如 “H2O2He3Mg4” 也是化学式。
由括号括起的化学式并佐以数字(可选择性添加)也是化学式。

例如 “(H2O2)” 和 “(H2O2)3” 是化学式。
返回所有原子的数量,格式为:第一个(按字典序)原子的名字,跟着它的数量(如果数量大于 1),然后是第二个原子的名字(按字典序),跟着它的数量(如果数量大于 1),以此类推。

示例 1:
输入:formula = “H2O”
输出:“H2O”
解释:原子的数量是 {‘H’: 2, ‘O’: 1}。

示例 2:
输入:formula = “Mg(OH)2”
输出:“H2MgO2”
解释:原子的数量是 {‘H’: 2, ‘Mg’: 1, ‘O’: 2}。

示例 3:
输入:formula = “K4(ON(SO3)2)2”
输出:“K4N2O14S4”
解释:原子的数量是 {‘K’: 4, ‘N’: 2, ‘O’: 14, ‘S’: 4}。

示例 4:
输入:formula = “Be32”
输出:“Be32”

提示:

  • 1 <= formula.length <= 1000
  • formula 由英文字母、数字、’(’ 和 ‘)’ 组成
  • formula 总是有效的化学式
  • 输出的所有值总是在 32-bit 整数范围内

本题并没有特别复杂、特别难理解的思路,但是对于各种情况需要妥善地加以处理,再配合递归的思想和 map 即可解出。

首先我们来分析以下,我们在遍历给定的字符串的时候会遇到以下几种情况:

  1. 常规情况

    这里的情况指的是常规的字符和数字,即没有括号的情况。在这种情况下,我们知道,大写字母及其后跟着的小写字母表示的是化学元素的名称;而元素名称后面又有两种情况,一是后面直接跟其他大写字母,这种情况下即元素个数缺省,默认为1,另一种情况是后面跟着数字,则数字表示该元素的原子个数。

  2. 括号

    括号及嵌套括号的出现是这个题要仔细处理的一个情况。对于这种多层括号嵌套,最里面的括号中就是我们上面的常规情况,而不同级的括号嵌套这种情况非常适合我们用递归的方式进行处理。

在具体实现中,我们将遍历字符串中遇到的字符分为以下三种情况:

  1. 遇到 (

    当遇到左括号时,我们要开始准备递归,在这种情况下,对当前括号里的子串进行递归调用,并用一个子 map 来接收当前括号内子串的原子名称及个数。当我们遇到有括号会退出递归函数,注意当退出递归函数时我们需要记录其后面的一个数字,并将它乘到我们的子串得到的子 map 所统计的原子个数上。

  2. 遇到 )

    遇到右括号时,我们肯定在之前遇到过一个左括号并进入递归函数,这时我们只需返回,并让遍历索引往后走一步即可。

  3. 其他情况

    其他情况即上述常规情况,我们遇到的是代表原子名称的字母和代表原子个数的数字。我们会分别实现两个函数来获取原子名称和个数。

其他需要注意的点:

  • 题目中要求的字典序,map 会自动帮我们排序。
  • 整个过程中维护的遍历索引 i 需要再函数间传递时使用引用传递。

完整代码:

class Solution {
private:
    int get_num(string& s, int& i) {
        string num = "";
        while (isdigit(s[i])) {
            num += s[i++];
        }
        return num.empty() ? 1 : stoi(num);
    }

    string get_name(string& s, int& i) {
        string name = "";
        while (isalpha(s[i]) && (name.empty() || islower(s[i]))) {
            name += s[i++];
        }
        return name;
    }

    map<string, int> get_map(string& s, int& i) {
        map<string, int> ans;
        while (i != s.length()) {
            if (s[i] == '(') {
                map<string, int> temp = get_map(s, ++i);
                int cnt = get_num(s, i);
                for (auto& kv : temp) {
                    ans[kv.first] += kv.second * cnt;
                }
            }
            else if (s[i] == ')') {
                ++i;
                return ans;
            }
            else {
                string name = get_name(s, i);
                int cnt = get_num(s, i);
                ans[name] += cnt;
            }
        }
        return ans;
    }

public:
    string countOfAtoms(string formula) {
        int i = 0;
        string ans;
        for (auto& kv : get_map(formula, i)) {
            ans += kv.first;
            if (kv.second > 1) {
                ans += to_string(kv.second);
            }
        }
        return ans;
    }
};

Ref:

https://leetcode-cn.com/problems/number-of-atoms/

https://riba2534.blog.csdn.net/article/details/88591566

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值