求Python实现O(n)时间、O(1)空间复杂度的无效括号移除算法
解决移除无效括号的O(n)时间、O(1)空间方案
嘿,这个需求确实有点挑战性——毕竟常规的栈解法虽然时间O(n)但空间也是O(n),而你要的是严格O(1)额外空间(除了输入存储之外)的线性时间解法。不过咱们可以通过两次线性遍历实现,不需要额外的数据结构,只用几个计数器就能搞定。
核心思路
我们分两步处理:
第一步:从左到右遍历,移除多余的右括号
用两个计数器open_count(记录当前有效的左括号数量)和close_count(记录当前有效的右括号数量)。遍历每个字符:- 遇到左括号:
open_count += 1,保留这个字符 - 遇到右括号:如果
open_count > close_count,说明这个右括号能匹配到左括号,close_count += 1,保留它;否则跳过这个右括号(因为没有对应的左括号匹配)
这一步之后,所有多余的右括号都被移除了,但可能还存在多余的左括号。
- 遇到左括号:
第二步:从右到左遍历,移除多余的左括号
同样用两个计数器,但这次优先保证右括号的匹配:- 遇到右括号:
close_count += 1,保留这个字符 - 遇到左括号:如果
close_count > open_count,说明这个左括号能匹配到右括号,open_count += 1,保留它;否则跳过这个左括号
这一步处理掉所有多余的左括号,最终得到的就是有效的括号字符串。
- 遇到右括号:
因为我们可以直接在字符数组上原地修改(Python字符串不可变,所以先转成列表),整个过程只用了几个计数器,额外空间是O(1),两次遍历总时间是O(n)。
Python 实现代码
def remove_invalid_parentheses(s: str) -> str: # 第一步:左到右移除多余的右括号 chars = list(s) open_count = close_count = 0 idx = 0 for c in chars: if c == '{': open_count += 1 chars[idx] = c idx += 1 elif c == '}': if open_count > close_count: close_count += 1 chars[idx] = c idx += 1 # 截断到第一步处理后的长度 chars = chars[:idx] # 第二步:右到左移除多余的左括号 open_count = close_count = 0 idx = len(chars) - 1 for c in reversed(chars): if c == '}': close_count += 1 chars[idx] = c idx -= 1 elif c == '{': if close_count > open_count: open_count += 1 chars[idx] = c idx -= 1 # 截断到第二步处理后的长度 return ''.join(chars[idx+1:]) # 测试示例 input_str = "{}{}{{}}}}}{{{{{}" output_str = remove_invalid_parentheses(input_str) print(f"Input: {input_str}") print(f"Output: {output_str}") # 输出: {}{}{{}}{}
边界情况测试
这个解法能处理各种边界场景:
- 全左括号输入:
"{{{{{"→ 输出空字符串(因为没有右括号匹配) - 全右括号输入:
"}}}}}"→ 输出空字符串 - 空字符串:输入
""→ 输出"" - 部分有效部分多余:
"{}}{{}"→ 输出"{}" - 完全有效:
"{}{{}}"→ 输出原字符串
为什么这个方案满足复杂度要求?
- 时间复杂度O(n):两次线性遍历,每次遍历都是O(n),总时间还是O(n)
- 空间复杂度O(1):除了将字符串转成列表(这是输入存储的必要转换,不算额外空间),我们只使用了几个计数器变量,额外空间是常数级的O(1)
内容的提问来源于stack exchange,提问作者Sai Addanki
相关产品推荐
相关产品推荐

