Problem

Given the head of a singly linked list, reverse the list, and return the reversed list.

https://leetcode.com/problems/reverse-linked-list/

Example 1:

case1

Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]

Example 2:

case2

Input: head = [1,2]
Output: [2,1]

Example 3:

Input: head = []
Output: []

Constraints:

  • The number of nodes in the list is the range [0, 5000].
  • -5000 <= Node.val <= 5000

Follow up: A linked list can be reversed either iteratively or recursively. Could you implement both?

Test Cases

1
2
3
4
5
6
7
# 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: Optional[ListNode]) -> Optional[ListNode]:
solution_test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pytest

from solution import Solution
from solution_recursive import Solution as SolutionRecursive
from utils import build_linked_list, format_linked_list

@pytest.mark.parametrize('head, expected', [
([1,2,3,4,5], [5,4,3,2,1]),
([1,2], [2,1]),
([], []),
])
class Test:
def test_solution(self, head, expected):
sol = Solution()
result = sol.reverseList(build_linked_list(head))
assert format_linked_list(result) == expected

def test_solution_recursive(self, head, expected):
sol = SolutionRecursive()
result = sol.reverseList(build_linked_list(head))
assert format_linked_list(result) == expected

Thoughts

非递归版比递归版更简洁。

时间复杂度 O(n)。空间复杂度,非递归版是 O(1),递归版是 O(n)

Code

Iteratively

solution.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from typing import Optional

from utils import ListNode


# 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: Optional[ListNode]) -> Optional[ListNode]:
prev = None
while head:
head.next, prev, head = prev, head, head.next

return prev

Recursively

solution_recursive.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from typing import Optional

from utils import ListNode


# 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: Optional[ListNode]) -> Optional[ListNode]:
if head is None:
return None

return self._helper(head)

def _helper(self, head: ListNode) -> ListNode:
if (next := head.next) is None:
return head

first = self._helper(next)
next.next = head
head.next = None
return first