代码随想录第八天刷题
第一题:反转字符串
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 时执行
# - 作为程序入口
以上代码均出自代码随想录
最后的一个为自己今日所学的内容,或者说之前不理解的,在本次三道题目出错的内容,是之后写代码需要及时复习的。今天笔记很乱,明天的博客应该是写一道题目,做一道的笔记,会更加容易一些。
