变量何时及如何更新?以罗马数字转整数代码重构为例
罗马数字转整数代码重构与变量更新原理解答
首先,你提出的通过循环内变量存储self.get_value(letter_list[x])结果的思路完全正确,先给你解释背后的原理,再给出优化后的代码。
变量更新的原理
你在循环内部定义letter0、letter1的逻辑没问题,变量能保持最新的原因很简单:
- 每次循环迭代时,代码会执行到变量赋值的那一行,此时会重新读取当前
letter_list的最新元素,调用get_value计算出最新值并赋值给变量。 - 这和函数无关,纯粹是循环的执行特性——循环体里的代码每一轮都会从头执行一遍,变量会被重新创建并赋值,自然能同步
letter_list的动态变化。 - 你之前遇到的变量不同步问题,大概率是把变量定义在循环外面,只赋值了一次,没有在每次循环里更新。而把赋值放在循环内部,就不会有这个问题。
重构后的代码(保留你的核心逻辑)
针对重复调用的问题,我们可以先把罗马数字字典初始化一次(避免每次get_value都转换列表),然后在循环内提前获取当前和下一个元素的值:
roman_numbers = [('I', 1), ('V', 5), ('X', 10), ('L', 50), ('C', 100), ('D', 500), ('M', 1000)] class Solution: def __init__(self): # 只初始化一次字典,避免重复转换提升效率 self.roman_dict = dict(roman_numbers) def get_value(self, number): return self.roman_dict[str(number)] def romanToInt(self, s: str) -> int: result = 0 letter_list = list(s) # 原循环变量letter没用到,换成_更符合Python习惯 for _ in s: try: # 提前获取当前和下一个元素的值,减少重复调用 current_val = self.get_value(letter_list[0]) next_val = self.get_value(letter_list[1]) if current_val >= next_val: result += current_val else: result -= current_val # 用pop(0)替代remove,逻辑更直接(明确删除第一个元素) letter_list.pop(0) except IndexError: # 处理最后一个元素 result += self.get_value(letter_list[0]) letter_list.pop(0) return result
更高效的优化版本(无需维护动态列表)
其实可以完全去掉letter_list,直接通过字符串索引遍历,这样避免了列表pop(0)的O(n)开销,代码也更简洁:
roman_numbers = [('I', 1), ('V', 5), ('X', 10), ('L', 50), ('C', 100), ('D', 500), ('M', 1000)] class Solution: def __init__(self): self.roman_dict = dict(roman_numbers) def romanToInt(self, s: str) -> int: result = 0 str_len = len(s) for i in range(str_len): current_val = self.roman_dict[s[i]] # 判断当前值是否小于下一个值,是则减,否则加 if i < str_len - 1 and current_val < self.roman_dict[s[i+1]]: result -= current_val else: result += current_val return result
这个版本没有任何重复调用,逻辑清晰,效率也更高,完全符合LeetCode的解题要求。
内容的提问来源于stack exchange,提问作者MIKIBURGOS
相关产品推荐
相关产品推荐

