理解作用域问题 - LeetCode 1640 解题报错求助
解决LeetCode 1640题时“局部变量‘found’在赋值前被引用”的问题
嘿,我来帮你捋清楚这个报错的问题!你遇到的这个错误,核心是对Python变量作用域的理解有点小偏差,咱们一步步拆解:
问题根源
你在嵌套的reverse函数里用了global s, found声明,但实际上s和found是外层canBeEqual函数的局部变量,不是定义在全局作用域(所有函数外面)的变量。当你用global关键字时,Python会直接去全局作用域找这两个变量,反而把外层函数的局部变量给屏蔽了——这就导致内部函数里的found变成了一个未赋值的局部变量,自然会触发“赋值前被引用”的报错。
修复方案
在Python的嵌套函数中,如果要修改外层函数的局部变量,应该用nonlocal关键字,它专门用来引用外层函数作用域的变量,而不是全局作用域。
另外,你原来的代码里直接修改arr变量会干扰后续的循环分支,我也顺便帮你调整了这一点,创建新的数组来传递给递归:
class Solution(object): def canBeEqual(self, target, arr): s = set() found = False def reverse(target, arr): nonlocal s, found # 替换global为nonlocal if found: return found if arr == target: found = True return found arr_tuple = tuple(arr) if arr_tuple in s: return False s.add(arr_tuple) for start in range(len(arr)): for end in range(start + 1, len(arr)): # 创建新数组,避免修改当前arr影响其他循环分支 new_arr = arr[:start] + arr[start:end+1][::-1] + arr[end+1:] reverse(target, new_arr) return found return reverse(target, arr)
额外优化:更高效的解法
其实这个题根本不需要用回溯这么复杂的思路!题目允许你任意次反转任意子数组,而通过反转操作,你可以把数组转换成任意相同元素组成的排列(类似冒泡排序,用相邻反转实现元素交换)。所以更高效的解法是直接判断两个数组的元素组成是否一致:
class Solution(object): def canBeEqual(self, target, arr): # 排序后对比,时间复杂度O(n log n) return sorted(target) == sorted(arr) # 或者用计数器,时间复杂度O(n) # from collections import Counter # return Counter(target) == Counter(arr)
这个解法不仅简洁,而且效率比回溯高太多,完全能通过所有测试用例。
内容的提问来源于stack exchange,提问作者MrJoe
相关产品推荐
相关产品推荐

