【Leetcode】随笔 - 实践
文章目录
你好呀!我是 山顶风景独好
欢迎踏入我的博客世界,能与您在此邂逅,真是缘分使然!
愿您在此停留的每一刻,都沐浴在轻松愉悦的氛围中。
这里不仅有丰富的知识和趣味横生的内容等您来探索,更是一个自由交流的平台,期待您留下独特的思考与见解。
让我们一起踏上这段探索与成长的旅程,携手挖掘更多可能,共同进步!✨
题目一:颜色分类(LeetCode 75)
题目分析:
给定一个包含红色、白色和蓝色、共
n个元素的数组nums,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。我们使用整数0、1和2分别表示红色、白色和蓝色。必须在不使用库内置的排序函数的情况下解决这个问题。例如:输入nums = [2,0,2,1,1,0],输出[0,0,1,1,2,2];输入nums = [2,0,1],输出[0,1,2]。
解题思路:
三指针法:通过三个指针分别追踪0的右边界、当前元素和2的左边界,一次遍历完成排序。
核心步骤:
- 初始化指针:
p0(0的右边界,初始为0)、current(当前元素,初始为0)、p2(2的左边界,初始为n-1)。 - 遍历数组,当
current <= p2时:- 若
nums[current] == 0,交换nums[current]和nums[p0],p0和current右移。 - 若
nums[current] == 2,交换nums[current]和nums[p2],p2左移(current不右移,因为交换过来的元素需重新判断)。 - 若
nums[current] == 1,current直接右移。
- 若
- 遍历结束后,数组已按0、1、2排序。
示例代码:
def sortColors(nums):
n = len(nums)
p0 = current = 0
p2 = n - 1
while current <= p2:
if nums[current] == 0:
# 交换当前元素和p0位置的元素
nums[current], nums[p0] = nums[p0], nums[current]
p0 += 1
current += 1
elif nums[current] == 2:
# 交换当前元素和p2位置的元素
nums[current], nums[p2] = nums[p2], nums[current]
p2 -= 1
else:
# 当前元素是1,直接后移
current += 1
# 测试示例
nums1 = [2,0,2,1,1,0]
sortColors(nums1)
print("排序后数组1:", nums1) # 输出:[0,0,1,1,2,2]
nums2 = [2,0,1]
sortColors(nums2)
print("排序后数组2:", nums2) # 输出:[0,1,2]
代码解析:
三指针分工明确:
p0左侧全为0,p2右侧全为1,p0到current之间全为1,current到p2之间是待处理元素。
通过一次遍历完成排序,时间复杂度为O(n),空间复杂度为O(1)(原地排序)。
交换0时current右移是因为交换过来的元素只能是1(p0到current之间已确认是1),而交换2时current不右移是因为交换过来的元素可能是0或1,需要重新判断。
题目二:字符串解码(LeetCode 394)
题目分析:
给定一个经过编码的字符串,返回它解码后的字符串。编码规则为:
k[encoded_string],表示其中方括号内部的encoded_string正好重复k次。注意k保证为正整数。例如:输入s = “3[a]2[bc]”,输出"aaabcbc";输入s = “3[a2[c]]”,输出"accaccacc";输入s = “2[abc]3[cd]ef”,输出"abcabccdcdcdef"。
解题思路:
栈:利用栈存储数字和字符串,遇到右括号时弹出栈顶的字符串和数字,进行解码并与栈顶剩余字符串拼接。
核心步骤:
- 初始化栈、当前数字(
num)和当前字符串(current_str)。 - 遍历字符串的每个字符:
- 若为数字,更新
num(可能是多位数)。 - 若为左括号,将
num和current_str入栈,重置num和current_str。 - 若为右括号,弹出栈顶的
prev_str和prev_num,更新current_str = prev_str + current_str * prev_num。 - 若为字母,直接拼接到
current_str。
- 若为数字,更新
- 遍历结束后,
current_str即为解码结果。
示例代码:
def decodeString(s):
stack = []
current_str = ""
num = 0
for char in s:
if char.isdigit():
# 处理多位数(如"123")
num = num * 10 + int(char)
elif char == '[':
# 入栈并重置
stack.append((current_str, num))
current_str = ""
num = 0
elif char == ']':
# 出栈并拼接
prev_str, prev_num = stack.pop()
current_str = prev_str + current_str * prev_num
else:
# 字母直接拼接
current_str += char
return current_str
# 测试示例
s1 = "3[a]2[bc]"
print("解码后字符串1:", decodeString(s1)) # 输出:"aaabcbc"
s2 = "3[a2[c]]"
print("解码后字符串2:", decodeString(s2)) # 输出:"accaccacc"
s3 = "2[abc]3[cd]ef"
print("解码后字符串3:", decodeString(s3)) # 输出:"abcabccdcdcdef"
代码解析:
栈的作用是保存左括号前的字符串和数字,当遇到右括号时,通过弹出栈顶元素实现嵌套解码(如"3[a2[c]]“先解码"2[c]“得到"cc”,再解码"3[acc]”)。
处理多位数时通过num = num * 10 + int(char)实现(如"123"拆分为1→12→123)。
时间复杂度为O(n)(n为解码后字符串的长度,每个字符处理一次),空间复杂度为O(n)(栈存储的字符总数)。
题目三:最长回文子串(LeetCode 5)
题目分析:
给你一个字符串
s,找到s中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。例如:输入s = “babad”,输出"bab"或"aba";输入s = “cbbd”,输出"bb"。
解题思路:
中心扩展法:回文串围绕中心对称(奇数长度中心是字符,偶数长度中心是两个字符之间),通过遍历每个可能的中心,向两侧扩展寻找最长回文子串。
核心步骤:
- 定义辅助函数
expand(left, right),返回以left和right为中心的最长回文子串的长度。 - 遍历字符串的每个索引,分别以该索引(奇数长度)和该索引与下一个索引(偶数长度)为中心,调用
expand函数。 - 记录最长回文子串的起始和结束索引,最终返回该子串。
示例代码:
def longestPalindrome(s):
if not s:
return ""
start = end = 0
def expand(left, right):
# 向两侧扩展,直到不满足回文条件
while left >= 0 and right <
len(s) and s[left] == s[right]:
left -= 1
right += 1
# 返回最长回文子串的长度(right - left - 1)
return right - left - 1
for i in range(len(s)):
# 奇数长度回文串(中心为i)
len1 = expand(i, i)
# 偶数长度回文串(中心为i和i+1)
len2 = expand(i, i + 1)
# 取最大长度
max_len = max(len1, len2)
# 更新最长回文子串的起始和结束索引
if max_len > end - start:
start = i - (max_len - 1) // 2
end = i + max_len // 2
return s[start:end + 1]
# 测试示例
s1 = "babad"
print("最长回文子串1:", longestPalindrome(s1)) # 输出:"bab"或"aba"
s2 = "cbbd"
print("最长回文子串2:", longestPalindrome(s2)) # 输出:"bb"
代码解析:
辅助函数
expand通过向两侧扩展,找到以left和right为中心的最长回文串长度,返回值为right - left - 1(因为退出循环时left和right已超出有效范围)。
遍历每个可能的中心(n个奇数中心和n-1个偶数中心),总时间复杂度为O(n²),空间复杂度为O(1)(仅使用常数变量)。
相比动态规划,中心扩展法空间更优,且实现简洁,适合解决此类问题。
✨ 这就是今天要分享给大家的全部内容了,我们下期再见!
我在CSDN等你哦!我的主页

浙公网安备 33010602011771号