代码随想录第八天刷题

第一题:反转字符串

class Solution(object):
    def subsitute_numbers(self, s):
        """
        :type s: str
        :rtype: str
        """
        
        count = sum(1 for char in s if char.isdigit()) # 统计数字的个数
        expand_len = len(s) + (count * 5)  # 计算扩充后字符串的大小, x->number, 每有一个数字就要增加几个长度
        res = [''] * expand_len
        
        new_index = expand_len - 1 # 指向扩充后字符串末尾
        old_index = len(s) - 1 # 指向原字符串末尾
        
        while old_index >= 0: # 从后往前, 遇到数字替换成“number”
            if s[old_index].isdigit():
                res[new_index-5:new_index+1] = "number"
                new_index -= 6
            else:
                res[new_index] = s[old_index]
                new_index -= 1
            old_index -= 1
        
        return "".join(res)
        
if __name__ == "__main__":
    solution = Solution()

    while True:
        try:
            s = input()
            result = solution.subsitute_numbers(s)
            print(result)
        except EOFError:
            break

第二题:反转字符串II

class Solution:
    def reverseStr(self, s: str, k: int) -> str:
        """
        1. 使用range(start, end, step)来确定需要调换的初始位置
        2. 对于字符串s = 'abc',如果使用s[0:999] ===> 'abc'。字符串末尾如果超过最大长度,则会返回至字符串最后一个值,这个特性可以避免一些边界条件的处理。
        3. 用切片整体替换,而不是一个个替换.
        """
        def reverse_substring(text):
            left, right = 0, len(text) - 1
            while left < right:
                text[left], text[right] = text[right], text[left]
                left += 1
                right -= 1
            return text
        
        res = list(s)

        for cur in range(0, len(s), 2 * k):
            res[cur: cur + k] = reverse_substring(res[cur: cur + k])
        
        return ''.join(res)

第三题:数字替换“number”

class Solution(object):
    def subsitute_numbers(self, s):
        """
        :type s: str
        :rtype: str
        """
        
        count = sum(1 for char in s if char.isdigit()) # 统计数字的个数
        expand_len = len(s) + (count * 5)  # 计算扩充后字符串的大小, x->number, 每有一个数字就要增加五个长度
        res = [''] * expand_len
        
        new_index = expand_len - 1 # 指向扩充后字符串末尾
        old_index = len(s) - 1 # 指向原字符串末尾
        
        while old_index >= 0: # 从后往前, 遇到数字替换成“number”
            if s[old_index].isdigit():
                res[new_index-5:new_index+1] = "number"
                new_index -= 6
            else:
                res[new_index] = s[old_index]
                new_index -= 1
            old_index -= 1
        
        return "".join(res)
        
if __name__ == "__main__":
    solution = Solution()

    while True:
        try:
            s = input()
            result = solution.subsitute_numbers(s)
            print(result)
        except EOFError:
            break
# ---------- LeetCode Python 重要规则 ----------
# 1. LeetCode 会这样调用我的代码:
#    Solution().singleNumber(nums)
#
# 2. 所以我必须:
#    - 在 singleNumber 方法里直接写逻辑
#    - 最后 return 一个结果
#
# 3. 不要在方法内部再定义同名函数

# ---------- 今日理解澄清 ----------
# 1. 这道题有两种解法:
#    - 哈希表(Python 常用,易理解)
#    - 异或(C 视频讲的解法,不用额外空间)

# 2. 「不使用额外空间」指的是:
#    尽量不要新建 dict / set / Counter 等数据结构

# 3. 我现在先掌握哈希解法,
#    异或解法先“看懂”,不要求立刻会写

# ---------- 反转字符串理解 ----------
# left, right = 0, len(s)-1
# 等价于:
# left = 0
# right = len(s) - 1

# 这种写法是为了同时初始化两个指针
# 功能上和我先算 l = len(s)-1 再赋值是一样的

# ---------- Day X:关于内部函数的规则 ----------
# 1. LeetCode 允许在类方法里定义辅助函数
# 2. 之前“不能有两个函数”是指:
#    - 不能定义同名函数覆盖入口函数
#    - 不能没有 return
# 3. 像 reverseStr 这种:
#    - 主函数负责流程
#    - 内部函数负责子问题(反转)
#    → 是非常推荐的写法


# ---------- 字符串转列表的理解 ----------
# 1. Python 的字符串是不可变的,不能直接改
# 2. 要原地修改字符串内容时:
#    res = list(s)       # 转成列表
#    ...                 # 在列表上操作
#    return ''.join(res) # 再拼回字符串
#
# 3. res = list(s) 的意义:
#    - 初始化一个可变对象
#    - 给后面逻辑用
#    - 起一个清晰的名字

# ---------- join 的理解 ----------
# ''.join(list) 是字符串方法
# 作用:把列表里的字符串用空字符串连接
#
# 例子:
# ['a','b','c'] → 'abc'
#
# 为什么要用:
# - 字符串不可变
# - 先 list(s) 修改
# - 最后 ''.join(res) 变回字符串


# ---------- range 三参数理解 ----------
# range(start, stop, step)
#
# 在 reverseStr 中:
# range(0, len(s), 2*k)
# - 0:从第一个字符开始
# - len(s):不超过字符串长度
# - 2*k:每 2k 个字符处理一次

# ---------- 列表切片 + 赋值理解 ----------
# res[cur : cur + k] 是切片
# 表示从 cur 开始,取 k 个元素
#
# 切片可以整体赋值:
# res[a:b] = new_list
#
# 在 reverseStr 中:
# 把切出来的子列表反转,再放回原位置


# ---------- sum + 生成器表达式 ----------
# sum(1 for x in s if 条件)
# 含义:统计满足条件的元素个数
#
# char.isdigit()
# 判断字符是否是数字 '0'~'9'
#
# 例子:
# s = "a1b2c3"
# sum(1 for c in s if c.isdigit()) = 3
'''
count = sum(1 for char in s if char.isdigit())
两者相等
count = 0
for char in s:
    if char.isdigit():
        count += 1
'''
# ---------- while old_index >= 0 的理解 ----------
# old_index 是下标,不是值
#
# old_index >= 0 表示:
# 下标还在字符串合法范围内
#
# 一旦 old_index == -1
# 说明已经处理完所有字符,循环结束

# ---------- 切片赋值理解 ----------
# res[new_index-5 : new_index+1] = "number"
#
# 实际覆盖的下标是:
# new_index-5, -4, -3, -2, -1, new_index
#
# 共 6 个位置,正好放下 "number"
#
# Python 切片规则:左闭右开


# ---------- new_index -= 6 的理解 ----------
# new_index 是下标,不是长度
#
# new_index -= 6
# 表示指针向左移动 6 个位置
#
# 因为:
# - 从后往前填充
# - "number" 占 6 个字符

# ---------- if __name__ == "__main__" 理解 ----------
# 1. 每个 Python 文件都有 __name__
# 2. 如果文件被直接运行:
#    __name__ == "__main__"
# 3. 如果是被 import:
#    __name__ == 文件名
#
# 用途:
# - 防止测试代码在被 import 时执行
# - 作为程序入口

以上代码均出自代码随想录

最后的一个为自己今日所学的内容,或者说之前不理解的,在本次三道题目出错的内容,是之后写代码需要及时复习的。今天笔记很乱,明天的博客应该是写一道题目,做一道的笔记,会更加容易一些。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务