LeetCode首唯一字符问题:Python字典自动排序致结果错误求助
问题:LeetCode「字符串中的第一个唯一字符」字典顺序异常
我正在解决LeetCode上的「字符串中的第一个唯一字符」问题,遇到了以下问题:
我的代码如下:
class Solution(object): def firstUniqChar(self, s): """ :type s: str :rtype: int """ hashmap = {x: 0 for x in list(s)} for char in s: hashmap[char] += 1 for k, v in hashmap.items(): if v == 1: index = s.index(k) return index
遇到的问题
- 将字符串转为字典时,字典会自动按字母顺序排列并去除重复字符。例如输入「leetcode」,转成列表是
[u'l', u'e', u'e', u't', u'c', u'o', u'd', u'e'],但打印字典显示为{u'c': 0, u'e': 0, u'd': 0, u'l': 0, u'o': 0, u't': 0}。 - 这导致遍历字典时,第一个找到的唯一字符不是原字符串中最先出现的(比如「leetcode」中应该是'l',但按字典顺序会先匹配到'c')。
- 同时,LeetCode环境中字符带有'u'前缀,而VSCode中运行同一代码时字典不会排序,也没有'u'前缀,代码能正常工作。
我需要让字典保持原字符串的字符顺序,从而找到原字符串中第一个出现的唯一字符。
解决方案
问题根源
你遇到的差异是因为LeetCode的运行环境大概率是Python 2,而VSCode中使用的是Python 3:
- Python 2的普通字典是无序的,会自动调整键的顺序;Python 3.7及以上的字典默认保留插入顺序。
- 字符前的'u'是Python 2中Unicode字符串的标识,Python 3中所有字符串都是Unicode,因此没有该前缀。
修复方案
方案1:使用OrderedDict维护插入顺序
通过collections.OrderedDict可以严格保留字符的插入顺序,解决排序问题:
from collections import OrderedDict class Solution(object): def firstUniqChar(self, s): """ :type s: str :rtype: int """ hashmap = OrderedDict() # 按字符串顺序统计字符出现次数 for char in s: if char not in hashmap: hashmap[char] = 0 hashmap[char] += 1 # 遍历有序字典,找到第一个计数为1的字符 for k, v in hashmap.items(): if v == 1: return s.index(k) # 无唯一字符时返回-1(原代码遗漏此逻辑) return -1
方案2:直接遍历原字符串(最优解)
不需要依赖字典顺序,先统计所有字符的出现次数,再遍历原字符串找到第一个计数为1的字符,时间复杂度O(n),效率更高:
class Solution(object): def firstUniqChar(self, s): """ :type s: str :rtype: int """ # 统计每个字符的出现次数 char_count = {} for char in s: char_count[char] = char_count.get(char, 0) + 1 # 遍历原字符串,返回第一个计数为1的字符索引 for idx, char in enumerate(s): if char_count[char] == 1: return idx # 无唯一字符返回-1 return -1
补充提示
- 原代码中
{x:0 for x in list(s)}会因字典键的唯一性重复覆盖相同字符,且Python 2中无法保留插入顺序,这是问题的核心。 - 方案2无需维护额外的有序结构,直接利用原字符串顺序,完全符合题目“第一个唯一字符”的要求,是更推荐的解法。
内容的提问来源于stack exchange,提问作者Caleb Bunch
相关产品推荐
相关产品推荐

