관리 메뉴

Mini

[알고리즘] 리트코드 19. 리스트 끝에서 N번째 노드 제거 c++ // 노드탐색 본문

Algorithm/연결리스트

[알고리즘] 리트코드 19. 리스트 끝에서 N번째 노드 제거 c++ // 노드탐색

Mini_96 2024. 7. 2. 17:55

https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/

* 내풀이

size를 찾고

prev값이 없길래 저장하고,

제거대상인 노드인경우, prev->next = cur->next로 바꿔줬다.

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

결과 :맨앞의 노드를 제거하는경우 오답이났음.

이경우는 head = head -> next를 리턴하면 됬다.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        

        auto cur = head;
        int sz=1;
        while(cur->next){
            cur=cur->next;
            sz++;
        }
        cout<<sz<<"\n";

        //예외처리
        if(sz==1 && n==1){
            return nullptr;
        }

        //맨앞을 제거하는경우
        if(sz==n){
            head = head->next;
            return head;
        }

        //그외
        cur = head;
        ListNode* prev = nullptr;
        while(cur){
            if(prev && sz==n){
                prev->next = cur->next;
                break;
            }
            prev = cur;
            cur = cur->next;
            sz--;
        }
        // if(cur->next == nullptr){
        //     cur->next = ListNode(sz);
        // }
        cout<<sz<<"\n";
        return head;
    }
};

 

* 개선

1. 복잡하게 생각할 필요없이

맨앞삭제하는경우 vs else 로 나누고

사이즈를 계산하고(len에 저장), 

len-n만큼 iter를 옮기면 삭제대상 직전위에 iter가 있다.

 

시간 복잡도: O(2 * N) , 여기서 N은 주어진 목록의 노드 수입니다. (사이즈계산순회 1회 , 구현순회 1회)
공간 복잡도: O(1) , 상수 공간만 사용되므로.

 

* 투포인터

- st, en을두고 둘의차이를 n만큼 유지하는게 핵심이다! //en을 n만큼 next로 이동시키면 된다.

- 이후 fast를 끝으로 보내고, slow와의 차이를 n으로 유지시키면 -> slow앞의 노드가 삭제대상노드가 된다!

- 맨앞노드를 제거하는 경우만 예외처리를 해줘야한다.

ex) 1->2 에서 1을제거 (n=2) // 2만큼 fast를 이동시키면 null을 가리키는 특징이 잇다. -> 즉, 이대는 맨앞을 제거해야함과 필요충분조건.

ListNode* removeNthFromEnd(ListNode* head, int n) {
	ListNode *fast = head, *slow = head;
	while(n--) fast = fast -> next;      // iterate first n nodes using fast
	if(!fast) return head -> next;       // if fast is already null, it means we have to delete head itself. So, just return next of head
	while(fast -> next)                  // iterate till fast reaches the last node of list
		fast = fast -> next, slow = slow -> next;            
	slow -> next = slow -> next -> next; // remove the nth node from last
	return head;
}

 

* 솔루션 링크

https://leetcode.com/problems/remove-nth-node-from-end-of-list/solutions/1164537/short-simple-one-pass-solution-w-explanation-beats-100-no-dummy-node-required/