文章目录
🌈你好呀!我是 山顶风景独好
🎈欢迎踏入我的博客世界,能与您在此邂逅,真是缘分使然!😊
🌸愿您在此停留的每一刻,都沐浴在轻松愉悦的氛围中。
📖这里不仅有丰富的知识和趣味横生的内容等您来探索,更是一个自由交流的平台,期待您留下独特的思考与见解。🌟
🚀让我们一起踏上这段探索与成长的旅程,携手挖掘更多可能,共同进步!💪✨
题目一:二叉树的层序遍历(LeetCode 102)
题目分析:
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。例如:输入root = [3,9,20,null,null,15,7],输出[[3],[9,20],[15,7]]。
解题思路:
广度优先搜索(BFS):利用队列辅助实现逐层遍历,记录每一层的节点值。
步骤:
- 若根节点为空,返回空列表。
- 初始化队列,将根节点加入队列。
- 循环处理每一层:
- 记录当前层的节点数量(队列长度)。
- 遍历当前层的所有节点,收集节点值,并将左右子节点加入队列(若存在)。
- 将当前层的节点值列表加入结果集。
- 返回结果集。
示例代码:
from collections import deque
# 二叉树节点定义
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def levelOrder(root):
if not root:
return []
result = []
q = deque([root]) # 初始化队列
while q:
level_size = len(q) # 当前层的节点数
level = [] # 存储当前层的节点值
for _ in range(level_size):
node = q.popleft()
level.append(node.val)
# 加入下一层节点
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
result.append(level)
return result
# 辅助函数:构建二叉树
def build_tree(values):
if not values:
return None
root = TreeNode(values[0])
queue = [root]
i = 1
while queue and i < len(values):
node = queue.pop(0)
if values[i] is not None:
node.left = TreeNode(values[i])
queue.append(node.left)
i += 1
if i < len(values) and values[i] is not None:
node.right = TreeNode(values[i])
queue.append(node.right)
i += 1
return root
# 测试示例
if __name__ == "__main__":
# 构建示例树:[3,9,20,null,null,15,7]
root = build_tree([3,9,20,None,None,15,7])
print("层序遍历结果:", levelOrder(root)) # 输出:[[3],[9,20],[15,7]]
代码解析:
使用队列存储每一层的节点,通过level_size控制每层的遍历范围,确保每次只处理当前层的节点。
遍历当前层节点时,将其左右子节点加入队列,为下一层遍历做准备,实现逐层访问。
结果集中每个子列表对应一层的节点值,顺序为从左到右。
时间复杂度为O(n)(n为节点总数,每个节点访问一次),空间复杂度为O(n)(队列最多存储一层节点,最坏情况为满二叉树的最后一层)。
题目二:有效的括号(LeetCode 20)
题目分析:
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
例如:输入s = “()”,输出true;输入s = “()[]{}”,输出true;输入s = “(]”,输出false。
解题思路:
栈:利用栈的先进后出特性匹配括号,遇到左括号入栈,遇到右括号则与栈顶元素比较,若匹配则出栈,否则无效。
步骤:
- 初始化栈,创建括号映射字典(右括号对应左括号)。
- 遍历字符串中的每个字符:
- 若为左括号,入栈。
- 若为右括号:
- 若栈为空或栈顶元素与当前右括号不匹配,返回false。
- 否则,栈顶元素出栈。
- 遍历结束后,若栈为空(所有左括号都匹配),返回true;否则返回false。
示例代码:
def isValid(s):
stack = []
# 右括号到左括号的映射
bracket_map = {')': '(', '}': '{', ']': '['}
for char in s:
if char in bracket_map:
# 处理右括号:检查栈顶是否匹配
top_element = stack.pop() if stack else '#'
if bracket_map[char] != top_element:
return False
else:
# 左括号入栈
stack.append(char)
# 栈为空说明所有括号都匹配
return not stack
# 测试示例
if __name__ == "__main__":
s1 = "()"
print("字符串{}是否有效:".format(s1), isValid(s1)) # 输出:True
s2 = "()[]{}"
print("字符串{}是否有效:".format(s2), isValid(s2)) # 输出:True
s3 = "(]"
print("字符串{}是否有效:".format(s3), isValid(s3)) # 输出:False
代码解析:
通过栈存储左括号,当遇到右括号时,必须与最后一个未匹配的左括号(栈顶)匹配,否则字符串无效。
bracket_map字典用于快速查找右括号对应的左括号,简化匹配逻辑。
遍历结束后,若栈中仍有元素,说明存在未匹配的左括号,返回false;否则返回true。
时间复杂度为O(n)(n为字符串长度,每个字符处理一次),空间复杂度为O(n)(栈最多存储n/2个左括号)。
题目三:合并两个有序链表(LeetCode 21)
题目分析:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。例如:输入l1 = [1,2,4], l2 = [1,3,4],输出[1,1,2,3,4,4]。
解题思路:
迭代法:使用虚拟头节点简化边界处理,通过双指针遍历两个链表,每次选择较小的节点连接到结果链表。
步骤:
- 创建虚拟头节点dummy和当前指针current,current初始指向dummy。
- 当两个链表都不为空时:
- 若l1节点值 <= l2节点值,current的next指向l1,l1后移。
- 否则,current的next指向l2,l2后移。
- current后移。
- 将剩余非空的链表连接到current的next。
- 返回dummy.next(新链表的头节点)。
示例代码:
# 链表节点定义
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeTwoLists(l1, l2):
# 创建虚拟头节点
dummy = ListNode(0)
current = dummy
# 遍历两个链表,选择较小的节点连接
while l1 and l2:
if l1.val <= l2.val:
current.next = l1
l1 = l1.next
else:
current.next = l2
l2 = l2.next
current = current.next
# 连接剩余节点
current.next = l1 if l1 else l2
return dummy.next
# 辅助函数:将列表转换为链表
def list_to_linkedlist(lst):
dummy = ListNode(0)
current = dummy
for val in lst:
current.next = ListNode(val)
current = current.next
return dummy.next
# 辅助函数:将链表转换为列表
def linkedlist_to_list(head):
result = []
current = head
while current:
result.append(current.val)
current = current.next
return result
# 测试示例
if __name__ == "__main__":
l1 = list_to_linkedlist([1,2,4])
l2 = list_to_linkedlist([1,3,4])
merged = mergeTwoLists(l1, l2)
print("合并后的链表:", linkedlist_to_list(merged)) # 输出:[1,1,2,3,4,4]
代码解析:
虚拟头节点dummy避免了单独处理头节点的情况,current指针用于构建结果链表。
通过比较l1和l2的当前节点值,选择较小的节点加入结果链表,确保升序特性。
当其中一个链表遍历完毕后,直接将另一个链表的剩余部分连接到结果链表末尾,无需逐个处理。
时间复杂度为O(m + n)(m、n分别为两个链表的长度,每个节点访问一次),空间复杂度为O(1)(仅使用常数变量)。
✨ 这就是今天要分享给大家的全部内容了,我们下期再见!😊
🏠 我在CSDN等你哦!我的主页😍