# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        # only 1 listnode
        if head.next == None:
            return None
        # when n equals to length of linked list
        tmp = head
        if self.listNodeLen(tmp) == n:
            return head.next
        
        # go to (n+1)th node from end of list
        while self.isNthFromEnd(tmp, n+1) == False:
            tmp = tmp.next
        # remove nth node from end of list
        if tmp.next.next == None: 
            tmp.next = None
        else:
            tmp.next = tmp.next.next
        return head
    
    def isNthFromEnd(self, head: Optional[ListNode], n: int) -> bool:
        tmp = head
        for _ in range(n):
            tmp = tmp.next if tmp else tmp
        
        if tmp == None:
            return True
        
        return False
    
    def listNodeLen(self, head: Optional[ListNode]) -> int:
        node_len = 0
        while head:
            node_len += 1
            head = head.next
        
        return node_len
        
22년도에 들었던 자료구조 수업이 새록새록 생각난다. 그때는 분명히 python을 훨씬 더 잘했던 것 같은데, 그때의 나로 돌아가기에는 시간이 좀 걸릴 것 같다.
이번부터 코드를 쓸 때 다른 사람이 읽을 코드라고 생각하고 쓰기로 했다.
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        # Create a dummy node to handle edge cases (e.g., removing the head node)
        dummy = ListNode(0, head)
        first = dummy
        second = dummy
        # Move the first pointer n + 1 steps ahead
        for _ in range(n + 1):
            first = first.next
        # Move both pointers until the first pointer reaches the end
        while first:
            first = first.next
            second = second.next
        # Remove the nth node from the end
        second.next = second.next.next
        return dummy.next
이것도 two pointer 문제였다. 뒤에서 n번째 노드를 찾기 위해서 나는 method를 활용해 하나하나씩 확인하고 edge case별로 코드를 작성해야 했다. 반면 gpt는 dummy를 이용해 edge case를 다루었고, 두 개의 포인터를 이용해 뒤에서 n번째 노드를 바로 구했다.