🏠 总目录📚 本教程 08 · 字符串与输入:脏输入也要有边界 ← →
📑 本页目录(点开跳转)

08 · 字符串与输入:脏输入也要有边界

⏱ 10 分钟 | atoi、回文、翻转单词、字符流


🎯 一句话

字符串题的本质常常是一个小状态机:当前读到哪里、已经确认了什么、下一类字符还允不允许出现。

🧩 题 1:把字符串转换成整数(atoi)

顺序固定:跳空格 → 读正负号 → 连续读数字 → 处理溢出。任何一步不符合规则就停止,而不是“尽量猜”。

def my_atoi(text):
    index, sign, value = 0, 1, 0
    while index < len(text) and text[index].isspace():
        index += 1
    if index < len(text) and text[index] in '+-':
        sign = -1 if text[index] == '-' else 1
        index += 1
    while index < len(text) and text[index].isdigit():
        value = value * 10 + int(text[index])
        index += 1
    value *= sign
    return max(-(2**31), min(2**31 - 1, value))


assert my_atoi('   -42x') == -42
assert my_atoi('words and 9') == 0
assert my_atoi('91283472332') == 2**31 - 1

🧩 题 2:最长不含重复字符的子字符串

窗口的左边界只向右走。每次遇到重复字符,就把左边界跳到它上一次出现位置的后一格。

def longest_unique(text):
    last_seen, left, best = {}, 0, 0
    for right, char in enumerate(text):
        if char in last_seen and last_seen[char] >= left:
            left = last_seen[char] + 1
        last_seen[char] = right
        best = max(best, right - left + 1)
    return best


assert longest_unique('abcabcbb') == 3
assert longest_unique('bbbbb') == 1

🧩 题 3:字符流中第一个不重复的字符

一边读一边维护两个事实:每个字符出现次数,以及第一次出现的顺序。队首若已经重复就淘汰。

from collections import Counter, deque


class FirstUniqueStream:
    def __init__(self):
        self.counts, self.queue = Counter(), deque()

    def insert(self, char):
        self.counts[char] += 1
        self.queue.append(char)
        while self.queue and self.counts[self.queue[0]] > 1:
            self.queue.popleft()

    def first_unique(self):
        return self.queue[0] if self.queue else '#'


stream = FirstUniqueStream()
for char in 'google':
    stream.insert(char)
assert stream.first_unique() == 'l'

🔗 这一章连到哪里

去哪 为什么
Python 会咬你的地方 09 · 容器、哈希与顺序 ⭐ 题 3 靠的是 Counter + deque 和「第一次出现的顺序」。那一章讲这批容器各自保不保序:dict 从 3.7 起保证插入序,set 从来不保证,而且它的实际顺序每次进程启动都会变

🛑 可以停在这里

看到字符串解析题,先列出合法阶段,而不是先写一堆 if。阶段明确,边界自然会出现。


✅ 检查点

最长无重复子串为什么左边界从不回退?

👀 看答案

右边界已经向右扩展;回退左边界只会把已知会冲突的字符重新放回窗口,既无帮助又会重复计算。


⚡ 走神救援

下一步: 回到 00 · 怎么刷代码题,挑一题遮住代码重写。

继续: 附录A · 速查

打卡记录保存在你的浏览器里,首页能看到总进度