Remove Nth Node From End of List

Remove Nth Node From End of List


연결 리스트의 head가 주어질때 뒤에서 n번째 노드를 제거한 후 head를 리턴

제약사항
1. 리스트의 노드의 숫자는 size로 한다.
2. 1 <= size <= 30
3. 0 <= Node.val <= 100
4. 1 <= n <= size

LeetCode 19. Remove Nth Node From End of List

Example 1:

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

Example 2:

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

Example 3:

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

Solution

/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
const removeNthFromEnd = (head, n) => {
let prev = head, next = head;
// block 1)
while(n--) {
next = next.next;
}

// block 2)
while(next && next.next) {
prev = prev.next;
next = next.next;
}

// block 3)
if(!next) {
head = head.next;
// block 4)
} else {
prev.next = prev.next ? prev.next.next : null;
}

return head;
};

Block 1)

let prev = head, next = head;
while(n--) {
next = next.next;
}

먼저 제거할 타겟의 이전 노드와 다음 노드를 알아내기 위해 prev, next변수를 선언하고 nextn번 만큼 움직인다.


Block 2)

while(next && next.next) {
prev = prev.next;
next = next.next;
}

그 뒤 next가 끝에 도달할 때 까지 prev와 같이 움직여주면 prev는 타겟의 이전 노드가 된다.

1 - 2 - 3 - 4(target) - 5 인 리스트가 있을 때 먼저 n만큼 next를 움직이면 다음과 같다.

1(prev) - 2 - 3(next) - 4(target) - 5

그리고 next가 끝에 도달할 때 까지 prev를 같이 움직이면 최종적으로 다음과 같다.

1 - 2 - 3(prev) - 4(target) - 5(next)


Block 3)

if(!next) {
head = head.next;
}

두 번째 while문은 next의 다음 노드가 없을 때는 실행하지 않기 때문에 위의 블록에 진입했다면

첫 번째 while문에서 이미 nextnull이 된것이다. 이 경우는 head가 지워지는 노드이다.

따라서, headhead.next를 주입한다. head.next에 아무것도 없다면 자연스럽게 null을 리턴할것이다.


Block 4)

else {
prev.next = prev.next ? prev.next.next : null;
}

prev는 타겟의 왼쪽 노드로 만약 타겟이 있다면 prev.next에 타겟의 .next를 주입한다.

만약 아무것도 없다면 null을 주입한다.


return head;

마지막으로 head를 리턴하면 문제가 해결된다.

Author

HandsomeJ

Posted on

2021-03-29

Updated on

2021-07-08

Licensed under

댓글