Python嵌套函数无法访问外部变量flag的问题及Java转Python优化
问题排查与解决方案
一、UnboundLocalError 原因与修复
1. 错误根源
你遇到的UnboundLocalError是Python作用域规则导致的:如果嵌套函数里对外部变量做赋值操作,Python会默认将其视为局部变量,哪怕外部已经定义了该变量。如果在赋值前先读取这个变量,就会触发未绑定局部变量的错误。比如你的permute函数里如果有flag = True这类赋值语句,Python就会把flag当成permute的局部变量,但你在赋值前又访问了它,自然报错。
2. 修复方法
有两种简单的修复方式:
- 用
nonlocal关键字声明:在permute函数开头添加nonlocal flag,明确告诉Python该变量来自外层嵌套作用域,而非局部变量。 - 用可变容器包裹变量:把
flag放在一个列表(可变对象)里,比如flag = [False],在permute函数里通过flag[0] = True修改值。因为修改容器内的元素不会触发局部变量判定,Python会直接使用外层的列表对象。
二、更高效的排列子串问题 Python 解法
用全排列枚举的方法效率极低(时间复杂度为O(n!),n是s1的长度),LeetCode上大概率会超时,推荐用滑动窗口+字符频率统计的方案,时间复杂度仅为O(len(s2)):
1. 思路说明
- 统计s1中每个字符的出现频率;
- 在s2上滑动一个长度等于s1的窗口,实时统计窗口内的字符频率;
- 每次窗口移动时,只需要更新移出窗口的左侧字符和移入窗口的右侧字符的频率,无需重新统计整个窗口;
- 只要某一窗口的频率和s1的频率完全匹配,就说明存在符合条件的子串。
2. 代码实现
def checkInclusion(s1: str, s2: str) -> bool: len1, len2 = len(s1), len(s2) if len1 > len2: return False # 用数组统计小写字母的频率(比字典更高效) count_s1 = [0] * 26 count_window = [0] * 26 # 初始化第一个窗口的频率 for i in range(len1): count_s1[ord(s1[i]) - ord('a')] += 1 count_window[ord(s2[i]) - ord('a')] += 1 if count_s1 == count_window: return True # 滑动窗口遍历剩余部分 for i in range(len1, len2): # 移除窗口左侧的字符 count_window[ord(s2[i - len1]) - ord('a')] -= 1 # 添加窗口右侧的新字符 count_window[ord(s2[i]) - ord('a')] += 1 if count_s1 == count_window: return True return False
内容的提问来源于stack exchange,提问作者heretoinfinity
相关产品推荐
相关产品推荐

