反转链表,设置两个指针变量,分别 指向前一个节点 和 当前节点,然后改变指针的next指向。有以下两种方式,两种思路一样,一种迭代的方式,一种是递归的方式。时间复杂度都是O(N)的,空间为O(1)
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
cur, pre = pHead, None
while cur:
cur.next, pre, cur = pre, cur, cur.next # 如果是Java/c++需要引入临时变量
return pre
"""
def ReverseList(self, pHead):
def recur(pre, cur):
# 递归边界
if not cur:return pre
# 递归
res = recur(cur, cur.next)
# 回溯
cur.next = pre
return res
return recur(None, pHead)
""" 本题的引申题目:给定区间的链表反转。
对于增加难度的反转链表,给定了左右边界,只对内部的子链进行反转。
思路:在本题的基础上,增加子链前后节点的标记;找到子链的左右位置,切断子链在整条链表中的左右连接,然后用本题的方式对子链进行反转;然后用子链前后的标记指针将左中右三部分穿起来。
class Solution:
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
def reverse_linked_list(head: ListNode): # 也可以使用递归反转一个链表
pre, cur = None, head
while cur:
# 将pre->cur转为pre<-cur,然后pre指向cur,cur指向下一个
cur.next, pre, cur = pre, cur, cur.next
# 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
dummy_node = ListNode(-1)
dummy_node.next = head
pre = dummy_node
# 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
for _ in range(left - 1):
pre = pre.next
# 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点
right_node = pre
for _ in range(right - left + 1):
right_node = right_node.next
# 第 3 步:切断出一个子链表(截取链表)
left_node = pre.next
curr = right_node.next
# 注意:切断链接
pre.next = None
right_node.next = None
# 第 4 步:同第 206 题,反转链表的子区间
reverse_linked_list(left_node)
# 第 5 步:接回到原来的链表中
pre.next = right_node
left_node.next = curr
return dummy_node.next 
京公网安备 11010502036488号