找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2598

积分

0

好友

350

主题
发表于 1 小时前 | 查看: 3| 回复: 0

今天遇到一件挺让人感慨的事。公司面试了一位45岁的技术架构,履历和能力没得说,技术面全票通过,但最后在薪资这关,发生了意想不到的转折。

一张社交媒体帖子截图,内容为一位用户分享面试45岁技术架构师的经历

对方开价25K,结合其腾讯T线背景和带团队的经验,这个要价其实很实在。领导那边好不容易沟通下来,批了这个预算。本以为板上钉钉,结果送他到电梯口时,他许是看出了我片刻的犹豫,主动改口说,月薪1.8万也能接受,只要底薪别压得太低就行。

那一刻的心情很复杂。一个技术和项目经验能“吊打”我们整个部门的人,却开始主动向下调整自己的预期。有网友总结,35岁之后找工作,最先失去的可能不是技术价值,而是那份议价的“体面”。这话听着刺耳,但在某些场景下,却显得格外真实。招聘方在评估时,年龄与成本的天平,时常会微妙地倾斜。

聊完这些,我们不妨切回技术本身。这次面试中,考了一道经典的算法题:原子的数量(LeetCode 726)。这道题很多人的第一反应是用正则或者各种字符串切片,但写着写着就容易乱,尤其是面对 K4(ON(SO3)2)2 这种嵌套复杂的化学式。

手算可能还能理清,但一旦要写成代码,括号嵌套、数字倍率、原子名大小写,这三者纠缠在一起,代码结构就容易变得混乱。解这道题,关键不是先想“怎么解析字符串”,而是先想清楚两件事:谁负责记录当前层级的原子数量,以及谁负责把括号后的倍率乘回去

本质上,这不是一道数学题,而是一个小型的语法解析题。最顺手的解法就是使用 栈 + 哈希表

核心思路

  1. 遇到左括号 (:意味着进入新的一层。将当前层的计数哈希表压入栈中,然后创建一个新的空哈希表,用于记录新层内的原子数量。
  2. 遇到右括号 ):意味着当前层结束。紧接着读取右括号后面的数字作为倍率(若无数字则默认为1)。将当前层哈希表中所有原子的数量乘以这个倍率,然后合并回栈顶的上一层哈希表中。
  3. 遇到原子(如 Mg, He, O:读取完整的原子名(大写字母开头,后跟零个或多个小写字母)。接着读取紧随其后的数字(若无则默认为1),并将数量累加到当前层的哈希表中。

解析过程中的难点在于原子名和数字的读取,以及括号嵌套倍率的正确处理。代码实现上,追求清晰远比追求奇技淫巧重要。一个指针顺序扫描的写法就足够清晰:

from collections import defaultdict

class Solution:
    def countOfAtoms(self, formula: str) -> str:
        stack = []
        cur = defaultdict(int)
        i, n = 0, len(formula)

        while i < n:
            ch = formula[i]

            if ch == '(':
                stack.append(cur)
                cur = defaultdict(int)
                i += 1

            elif ch == ')':
                i += 1
                num = 0
                while i < n and formula[i].isdigit():
                    num = num * 10 + int(formula[i])
                    i += 1
                num = num or 1

                top = stack.pop()
                for atom, cnt in cur.items():
                    top[atom] += cnt * num
                cur = top

            else:
                start = i
                i += 1
                while i < n and formula[i].islower():
                    i += 1
                atom = formula[start:i]

                num = 0
                while i < n and formula[i].isdigit():
                    num = num * 10 + int(formula[i])
                    i += 1
                cur[atom] += num or 1

        ans = []
        for atom in sorted(cur.keys()):
            ans.append(atom)
            if cur[atom] > 1:
                ans.append(str(cur[atom]))
        return ''.join(ans)

这段代码里,有两个细节最容易出错:

  1. 右括号 ) 后面的倍率读取:很多人一看到右括号就急着合并上一层,容易漏掉 )2)12 这种情况。这个数字必须完整读出来,因为它要乘以其所在的整个括号层内的所有原子计数。
  2. 原子名的读取:像 MgHe 这种,不能只读一个大写字母就结束。必须用一个循环,把后面连续的(如果存在)小写字母一起“吃掉”,直到遇到非小写字母字符为止。

为了更直观地理解这个过程,我们用 Mg(OH)2 走一遍流程:

  • 读到 Mg,当前层记录为 {'Mg': 1}
  • 遇到 (,将当前表 {'Mg': 1} 压栈,并新建一个空表 {}
  • 在新层里,先后读到 OH,记录为 {'O': 1, 'H': 1}
  • 遇到 ),读取后面的倍率 2
  • 将当前层原子数量乘以倍率,得到 {'O': 2, 'H': 2}
  • 将这一层合并回栈顶的上一层,得到 {'Mg': 1, 'O': 2, 'H': 2}
  • 最后按字典序排序输出:H2MgO2

这道题本身并不难,难点在于如何把解析过程组织得清晰、健壮。如果你一开始就用一堆散乱的 if-else 去拼凑,最后很可能栽在嵌套括号的倍率或多位数字的处理上。在这里的作用不是炫技,它就是一个最自然的“现场暂存区”,用来管理不同层级的上下文状态。

所以,面对这类算法题,或者任何需要解析嵌套结构的场景,先别急着去抠最终输出的字符串格式。把“进入/退出层级”和“应用倍率”这两个核心动作的数据结构想清楚,代码的脉络自然就顺畅了。多练习这类题目,能有效锻炼你对哈希表这两种基础数据结构的运用能力,这正是技术面试中常考的重点。在像云栈社区这样的开发者平台上,大家也常常交流这类题目的解法和调试心得,这对于巩固基础、应对面试非常有帮助。




上一篇:clawhub下载Skills限速?Node.js环境下登录即可解决
下一篇:Python FastMCP 实践指南:从零开始构建你的首个 MCP 协议服务器
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-21 06:46 , Processed in 0.501132 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表