力扣刷题(第四十九天)

灵感来源

  • 保持更新,努力学习

  • python脚本学习

反转链表

解题思路

  1. 迭代法:通过遍历链表,逐个改变节点的指针方向。具体步骤如下:

    • 使用三个指针:prev(初始为None)、curr(初始为头节点)、next_node(用于保存当前节点的下一个节点)。
    • 在遍历过程中,先保存当前节点的下一个节点,然后将当前节点的指针指向前一个节点,最后更新prev和curr指针。
    • 重复上述步骤,直到遍历完整个链表,此时prev指针即为新的头节点。
  2. 递归法:通过递归调用反转后续节点,然后调整当前节点的指针方向。具体步骤如下:

    • 递归反转当前节点的后续链表。

    • 将当前节点的下一个节点的指针指向当前节点。

    • 将当前节点的指针置为None,避免形成环。

      python 复制代码
      # Definition for singly-linked list.
      class ListNode:
          def __init__(self, val=0, next=None):
              self.val = val
              self.next = next
      
      class Solution:
          # 迭代方法
          def reverseList(self, head: ListNode) -> ListNode:
              prev = None
              curr = head
              while curr:
                  next_node = curr.next  # 保存下一个节点
                  curr.next = prev       # 反转指针
                  prev = curr            # 移动prev指针
                  curr = next_node       # 移动curr指针
              return prev                # 返回新的头节点
      
          # 递归方法
          def reverseListRecursive(self, head: ListNode) -> ListNode:
              if not head or not head.next:
                  return head
              # 递归反转后续节点
              new_head = self.reverseListRecursive(head.next)
              # 调整指针方向
              head.next.next = head
              head.next = None
              return new_head
      
      # 辅助函数:将列表转换为链表
      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__":
          # 创建链表 1->2->3->4->5
          head = list_to_linkedlist([1, 2, 3, 4, 5])
          
          # 使用迭代方法反转链表
          solution = Solution()
          reversed_head = solution.reverseList(head)
          print("迭代方法反转后的链表:", linkedlist_to_list(reversed_head))
          
          # 重新创建链表 1->2->3->4->5
          head = list_to_linkedlist([1, 2, 3, 4, 5])
          
          # 使用递归方法反转链表
          reversed_head_recursive = solution.reverseListRecursive(head)
          print("递归方法反转后的链表:", linkedlist_to_list(reversed_head_recursive))    

逐行解释

python 复制代码
# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val        # 当前节点的值
        self.next = next      # 指向下一个节点的指针

class Solution:
    # 迭代方法:通过遍历链表逐个反转指针方向
    def reverseList(self, head: ListNode) -> ListNode:
        prev = None           # 初始化前一个节点为None
        curr = head           # 初始化当前节点为头节点
        while curr:           # 遍历链表直到当前节点为空
            next_node = curr.next  # 保存当前节点的下一个节点
            curr.next = prev       # 将当前节点的指针指向前一个节点
            prev = curr            # 前一个节点向后移动
            curr = next_node       # 当前节点向后移动
        return prev                # 返回新的头节点(原链表的尾节点)

    # 递归方法:通过递归反转后续节点,再调整当前节点的指针
    def reverseListRecursive(self, head: ListNode) -> ListNode:
        if not head or not head.next:  # 递归终止条件:节点为空或为尾节点
            return head
        # 递归反转后续节点,返回新的头节点
        new_head = self.reverseListRecursive(head.next)
        # 调整指针方向:将当前节点的下一个节点的next指向当前节点
        head.next.next = head
        # 断开当前节点的next指针,防止形成环
        head.next = None
        return new_head                # 返回新的头节点

# 辅助函数:将列表转换为链表
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__":
    # 创建链表 1->2->3->4->5
    head = list_to_linkedlist([1, 2, 3, 4, 5])
    
    # 使用迭代方法反转链表
    solution = Solution()
    reversed_head = solution.reverseList(head)
    print("迭代方法反转后的链表:", linkedlist_to_list(reversed_head))
    
    # 重新创建链表 1->2->3->4->5
    head = list_to_linkedlist([1, 2, 3, 4, 5])
    
    # 使用递归方法反转链表
    reversed_head_recursive = solution.reverseListRecursive(head)
    print("递归方法反转后的链表:", linkedlist_to_list(reversed_head_recursive))
相关推荐
Evand J2 分钟前
【PMSM例程6】永磁同步电机(PMSM)基于增广EKF的d-q轴电感分阶段辨识算法|电机参数估计与误差分析
算法·matlab·电机·ekf
垆边人似月.3 分钟前
华为题:最多可以参加的会议数目
数据结构·c++·算法
Matlab程序猿6 分钟前
【MATLAB源码-第460期】基于matlab的OTFS通信系统SLM峰均比抑制及非线性功率放大器失真与误码性能仿真
开发语言·算法·matlab·slm·otfs
xiangyun617 分钟前
C++ list 模拟实现(一):手撕双向链表,从节点到迭代器
数据库·c++·算法·链表·stl·list
码爸9 小时前
线性回归算法
算法·机器学习·线性回归
Coder-magician9 小时前
《代码随想录》刷题打卡day51:图论-part09(dijistra堆优化,Bellman_ford算法)
算法·图论
Nil2089 小时前
leetcode 763划分字母区间
算法·leetcode·职场和发展
不会就选b10 小时前
算法日常・每日刷题--<动态规划>20
算法·leetcode·动态规划
青少儿编程课堂11 小时前
迪杰斯特拉(Dijkstra)算法:单源最短路与赛场路线规划
c++·python·算法·bfs·信息学竞赛
不会就选b11 小时前
算法日常・每日刷题--<动态规划>19
算法·leetcode·职场和发展