Description

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

Example 1:

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

Example 2:

  • 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?

Submitted Code

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution(object):
    def reverseList(self, head):
        """
        :type head: Optional[ListNode]
        :rtype: Optional[ListNode]
        """
        value_list = []   # 노드들의 값을 순서대로 저장할 리스트
        current = head    # 노드의 값을 바꾸기 위해 처음부터 다시 순회할 때 쓸 포인터
        result = head     # 완성된 연결 리스트를 리턴할 때 쓸 포인터

        while head:
            value_list.append(head.val)
            head = head.next

        for v in value_list[::-1]:
            current.val = v
            current = current.next

        return result

Runtime: 3 ms | Beats 16.75%
Memory: 14.22 MB | Beats 87.64%

연결 리스트를 순회하며 값들을 따로 저장한 후, 다시 연결 리스트를 처음부터 순회하며 값을 바꿔줬다. 많이 느리지만 더 빠르게 할 방법이 생각나지 않아서 일단 풀었다.

Other Solutions

1st

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        node = None             # head의 반대 방향의 노드(Null에서 시작)

        while head:
            temp = head.next    # head의 원래 방향의 다음 노드를 가리키는 임시 포인터
            head.next = node    # head가 반대 방향의 노드를 가리키도록 변경
            node = head         # 현재 head의 자리로 node 이동
            head = temp         # 현재 temp의 자리로 head 이동
        
        return node

time complexity: 𝑂(𝑛)
space complexity: 𝑂(1)

head(h) = [1, 2, 3]
node(n) = None

n   h          (○ = Null node)
○   1 → 2 → 3 → ○   
---------------------------------------------
n   h   t                       n   h
○ ← 1   2 → 3 → ○           ○ ← 1   2 → 3 → ○

    n   h   t                       n   h
○ ← 1 ← 2   3 → ○           ○ ← 1 ← 2   3 → ○

        n   h   t                       n   h
○ ← 1 ← 2 ← 3   ○           ○ ← 1 ← 2 ← 3   ○

return node(n) = [3, 2, 1]

2nd

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:   # base case: 빈 연결리스트이거나 노드가 한 개만 있을 때
            return head

        new_head = self.reverseList(head.next)
        head.next.next = head     # 현재 노드(head)의 다음 노드(head.next)가 현재 노드를 가리키도록 변경
        head.next = None          # 다음 노드(head.next)를 None으로 설정(기존 연결을 끊어서 무한 루프 방지)
        return new_head

재귀를 사용한 방법도 참고했다.

head = [1, 2, 3]

호출 단계          head   head.next      올라오는 단계        head   new_head
reverseList(1)    1        2       |   reverseList(2)     2        3
↓                                  |   ↓
reverseList(2)    2        3       |   reverseList(1)     1        3
↓                                  |                           
reverseList(3)    3        ○       |
            (base case, return 3)  |

return new_head = [3, 2, 1]

Leave a comment