[Hackerrank 문제 풀이] Insert a Node Into a Sorted Doubly Linked List

Junu Kim·2025년 11월 8일
0
post-thumbnail

[Linked List] Insert a Node Into a Sorted Doubly Linked List

난이도: ★☆☆☆☆ • solved on: 2025-11-08


문제 요약

  • 문제 유형: Linked List (이중 연결 리스트)
  • 요구사항: 정렬된 이중 연결 리스트(Doubly Linked List)에 주어진 데이터를 삽입해, 정렬 순서가 유지되도록 새 노드를 추가해야 한다.

사용 개념

  1. 자료구조

    • DoublyLinkedListNode
      prevnext 포인터를 동시에 가지는 노드 구조
  2. 알고리즘/기법

    • 순차 탐색(linear traversal)
    • 포인터 조작(pointer manipulation)
  3. 핵심 키워드

    • 삽입 위치 탐색
    • prev / next 연결 관리
    • 예외 처리 (맨 앞, 중간, 맨 뒤 삽입)

풀이 아이디어

  1. 문제 분해
  • 삽입할 위치를 찾기 위해 리스트를 순회한다.
  • 삽입 위치는 현재 노드의 값 ≤ data ≤ 다음 노드의 값인 곳이다.
  • 새 노드를 중간에 넣을 때는 prev / next를 모두 재연결해야 한다.
  • 맨 앞이나 맨 뒤 삽입 시 예외 처리를 별도로 수행한다.
  1. 핵심 로직 흐름

    if (data <= head.data)
        // 맨 앞 삽입
    else
        // 중간 또는 끝 탐색
        while (current != null)
            if (current.next == null)
                // 맨 뒤 삽입
            else if (current.data <= data <= current.next.data)
                // 중간 삽입
  2. 예외 처리

    • 리스트의 맨 앞: 기존 head보다 작은 값일 때 새 노드를 head로 지정
    • 리스트의 맨 뒤: 마지막 노드의 next가 null인 경우 연결 처리

코드

public static DoublyLinkedListNode sortedInsert(DoublyLinkedListNode llist, int data) {
    DoublyLinkedListNode llistCurrent = llist;
    DoublyLinkedListNode newItem = new DoublyLinkedListNode(data);

    // Case 1: 맨 앞에 삽입
    if (data <= llist.data) {
        newItem.next = llist;
        llist.prev = newItem;
        return newItem;
    }

    // Case 2: 중간 또는 맨 뒤 탐색
    while (llistCurrent != null) {
        // 마지막 노드일 경우 (맨 뒤 삽입)
        if (llistCurrent.next == null) {
            llistCurrent.next = newItem;
            newItem.prev = llistCurrent;
            break;
        }

        // 중간 삽입
        if (llistCurrent.data <= data && data <= llistCurrent.next.data) {
            newItem.next = llistCurrent.next;
            llistCurrent.next.prev = newItem;

            llistCurrent.next = newItem;
            newItem.prev = llistCurrent;
            break;
        }
        llistCurrent = llistCurrent.next;
    }
    return llist;
}

시간·공간 복잡도

  • 시간 복잡도: O(N) — 리스트를 순회하며 삽입 위치 탐색
  • 공간 복잡도: O(1) — 새 노드 1개만 추가

어려웠던 점

  • 처음에는 맨 뒤 삽입 시 예외 처리를 빠뜨려 NullPointerException이 발생했다.
    마지막 노드의 nextnull일 수 있다는 점을 간과했다.

배운 점 및 팁

  • 이중 연결 리스트에서는 prevnext 양쪽 포인터를 모두 업데이트해야 한다. → 순서에 주의

  • 연결 리스트 삽입 로직은 단순하지만, 포인터 연결 순서가 꼬이면 쉽게 오류가 발생하므로 단계적으로 디버깅하는 습관이 중요하다.


참고 및 링크


추가 연습 문제

  • 비슷한 유형 (GPT 추천):

  • 확장 문제 (GPT 추천):

    • 정렬되지 않은 리스트에 새 노드 삽입 후 자동 정렬 구현
profile
생각이 현실이 될 수 있도록 노력하는 중입니다.

0개의 댓글