https://leetcode.com/problems/reverse-linked-list/
Reverse Linked List - LeetCode
Can you solve this real interview question? Reverse Linked List - Given the head of a singly linked list, reverse the list, and return the reversed list. Example 1: [https://assets.leetcode.com/uploads/2021/02/19/rev1ex1.jpg] Input: head = [1,2,3,4,5] O
leetcode.com
본 포스팅은 <파이썬 알고리즘 인터뷰> 책에서 다룬 리트코드 문제들을 다루고 있으며, 문제 풀이의 많은 부분을 책의 힌트와 해설을 참고하였음을 알립니다.
문제
Given the head of a singly linked list, reverse the list, and return the reversed list.
주어진 단일 연결 리스트의 헤드를 받아서, 리스트를 역순으로하고, 역순으로 된 리스트를 반환하시오.

문제 이해
단일 연결 리스트는 두 가지 방법으로 뒤집을 수 있다.
1. 재귀 구조로 뒤집기
2. 반복 구조로 뒤집기 이다.
문제 풀이
- 재귀 구조로 뒤집기 (Recursive)
 
다음 노드(next)와 현재 노드(node)를 파라미터로 지정한 함수를 계속해서 재귀 호출한다.
이게 말은 어려운데 쉽게 말하면 맨 앞의 node를 하나씩 뒤로 옮겨주는 과정이다.
def reverseList(self, head: ListNode) -> ListNode:
    def reverse(node: ListNode, prev: ListNode = None):
    	# node: 현재노드, prev: 이전 노드 
        if not node:		# 만약 현재 노드가 없으면 (node가 None이면),
            return prev		# 이전 노드를 반환하고 종료 (기존 리스트의 끝에 도달 시 재귀를 멈추는 역할)
        # 현재 노드의 다음 노드(node.next)를 next로 저장
        # 현재 노드의 node.next를 이전 노드(prev)로 설정 
        next, node.next = node.next, prev
        
	# 재귀 호출을 통해 다음 노드(next)와 현재 노드(node)를 인자로 전달, 다시 reverse함수를 호출
        return reverse(next, node) 	
        
    return reverse(head)
- 반복 구조로 뒤집기 (Iterative)
 
node.next를 이전 prev 리스트로 계속 연결하면서 끝날 때까지 반복하는 과정이다.
next, node.next = node.next, prev 로 다중 할당하는 부분은 재귀나 반복 양쪽 모두 동일하게 진행된다.
def reverseList(self, head: ListNode) -> ListNode:
    node, prev = head, None		# node를 리스트의 헤드 노드로 설정, prev는 None으로 초기화
    
    while node:		# 현재 노드가 None이 될 때까지 반복
    	next, node.next = node.next, prev	# 리스트 방향이 역순으로 변경
        prev, node = node, next			# 이전 노드(prev) > 현재 노드(node), 현재 노드(node) > 다음 노드(next)로 갱신
        
    return prev		# prev가 새로운 헤드가 되며, 방향이 역순으로 변경된 상태
정답 코드
재귀 구조
# 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:
        def reverse(node: ListNode, prev: ListNode = None):
            if not node:
                return prev
            next, node.next = node.next, prev
            return reverse(next, node)
        return reverse(head)
반복 구조
# 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:
        node, prev = head, None
        while node:
            next, node.next = node.next, prev
            prev, node = node, next
        return prev
마치며
개인적으론 반복문을 통한 코드가 더 가독성이 좋게 느껴졌고 이해가 쉽기도 했다.
easy 난이도라는데 .. 나는 왜 이렇게 어렵게 느껴졌을까..★


'Algorithm > LeetCode' 카테고리의 다른 글
| [leetcode 198. python] 집 도둑 (House Robber) 풀이 (1) | 2024.01.23 | 
|---|---|
| [leetcode 29.python] 보석과 돌 (Jewels-and-stones) 풀이 (2) | 2024.01.05 | 
| [leetcode 225.python] 큐를 이용한 스택 구현 (Implement Stack using Queues) 풀이 (0) | 2024.01.04 | 
| [leetcode 561.python] 배열 파티션 1(Array-partition 1) 풀이 (3) | 2024.01.03 | 
| [leetcode 49.python] 그룹 애너그램 (Group Anagrams) 풀이 (2) | 2024.01.03 |