오늘 문제는 이전까지 푼 연결 리스트 문제들전에 풀었다면 도움이 됐을 문제입니다.
Given the head
of a singly linked list, return the middle node of the linked list.
If there are two middle nodes, return the second middle node.
Example 1:
Input: head = [1,2,3,4,5]
Output: [3,4,5]
Explanation: The middle node of the list is node 3.
Example 2:
Input: head = [1,2,3,4,5,6]
Output: [4,5,6]
Explanation: Since the list has two middle nodes with values 3 and 4, we return the second one.
Constraints:
[1, 100]
.1 <= Node.val <= 100
링크드 리스트가 주어졌을 때, 주어진 링크드 리스트의 중간 노드를 반환하는 문제입니다.
최근에 연결 리스트 문제를 정말 많이 풀고 있는데요. 거기서 나오는 문제들을 풀 때 사용했던 기술들을 활용한다면 금방 풀 것 같습니다.
입출력을 살펴보겠습니다.
문제는 간단합니다. 주어진 연결 리스트의 가운데 노드를 반환하면 해결되는 문제입니다.
그렇다면 이전 펠린드롬인지를 판별하는 문제가 기억나시나요? 절반까지 오고 나머지 절반을 뒤집어서 두 개를 비교하는 문제가 있었습니다. 해당 문제에서 투 포인터를 통해 절반까지 연결 리스트를 순회를 했었습니다. 이 방법을 활용한다면 금방 문제가 해결될 것으로 보입니다.
바로 코드 설계를 진행해보도록 하겠습니다.
s
)는 한 번에 한 칸씩 이동합니다.f
)는 한 번에 두 칸씩 이동합니다.f
는 s
보다 두 배 빠르게 리스트를 순회합니다.f
가 리스트의 끝에 도달했을 때:s
는 리스트의 중간에 위치하게 됩니다.f
는 2씩 이동하기 때문에 n/2 단계에서 끝에 도달합니다.s
는 n/2번 이동하며 중간에 도달합니다.# 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 middleNode(self, head):
"""
:type head: Optional[ListNode]
:rtype: Optional[ListNode]
"""
s, f = head, head
while f and f.next:
s = s.next
f = f.next.next
return s
s
)와 Fast 포인터(f
)를 head
로 초기화합니다.f
와 f.next
가 존재할 동안 반복합니다.s
는 한 번에 한 칸씩 이동하며, s = s.next
로 업데이트됩니다.f
는 한 번에 두 칸씩 이동하며, f = f.next.next
로 업데이트됩니다.s
는 중간 노드를 가리키게 됩니다.이번 문제는 비교적 간단하게 해결할 수 있는 문제입니다. 하지만 연결 리스트 문제들을 풀 때 자주 사용되는 투 포인터 방법을 학습할 수 있는 좋은 문제였습니다.
전체 테스트 케이스를 실험한 코드는 다음 링크에서 확인할 수 있습니다.
읽어주셔서 감사합니다!!
오늘도 화이팅!!