베어_
TechBear
베어_
전체 방문자
오늘
어제
  • 분류 전체보기 (336)
    • Spring (33)
      • 개념 (13)
      • Security (5)
      • 실습 (1)
      • 토비 스프링 (11)
    • JPA (6)
    • 프로젝트 기록 (24)
    • DB (13)
    • JAVA (18)
    • 알고리즘 (50)
      • 유형정리 (8)
      • Baekjoon (21)
      • LeetCode (18)
    • 디자인패턴 (0)
    • 개발서적 (79)
      • Effective Java (78)
      • 객체지향의 사실과 오해 (1)
    • 독후감 (4)
    • 보안 (2)
    • 운영체제(OS) (53)
      • 공룡책 (53)
    • 컴퓨터 네트워크 (28)
      • 컴퓨터 네트워크 하향식 접근 (23)
    • 자료구조 (1)
    • DevOps (2)
    • 앱 개발 (20)
      • 안드로이드 스튜디오 (20)

블로그 메뉴

    공지사항

    인기 글

    태그

    • Spring
    • 자바
    • 함수형인터페이스
    • 이펙티브자바
    • 알고리즘
    • dfs
    • 스프링
    • leetcode
    • BFS
    • jpa
    • 자바8
    • 데이터베이스
    • 토비스프링
    • 스프링시큐리티
    • 코드업
    • C++
    • 스레드
    • 백준
    • java
    • 운영체제

    최근 댓글

    최근 글

    티스토리

    hELLO · Designed By 정상우.
    베어_

    TechBear

    알고리즘/LeetCode

    [LeetCode] Reorder List (Java)

    2023. 7. 21. 01:04

    ✉️문제

    https://leetcode.com/problems/reorder-list/description/

     

    Reorder List - LeetCode

    Can you solve this real interview question? Reorder List - You are given the head of a singly linked-list. The list can be represented as: L0 → L1 → … → Ln - 1 → Ln Reorder the list to be on the following form: L0 → Ln → L1 → Ln - 1 → L2

    leetcode.com

     

    📝 접근 

    이 문제는 합병 정렬에 대한 기본적인 원리를 담고 있다. 먼저 어떻게 순서를 나열하는지 예제를 통해 알아보자. 

    (홀수 일 때) 1 -> 2 -> 3 -> 4   ========>  1 -> 4 -> 2 -> 3 
    (짝수 일 때) 1 -> 2 -> 3 -> 4 -> 5    ========>  1 -> 5 -> 2 -> 4 -> 3

    규칙을 찾기 위해 노드를 분리해보면 절반을 기준으로 first, second로 나눌 수 있으며, second 리스트는 마지막 노드에서 시작해서 거꾸로 이동한다.

    (first) 1, 2, 3
    (second) 4, 5 

    이렇게 코드를 절반으로 나누기 위해서 분할 과정을 거친다. 분할을 하기 위해 first는 노드를 한 번 이동하고 second는 두 번 이동시킨다. 이렇게 하면 리스트를 절반으로 나눌 수 있다.

    ListNode slow = root;
    ListNode fast = root.next;
    
    while(fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }

     

    리스트를 절반으로 분리했으니 이제 second의 리스트 방향을 반대로 바꿔주어야 한다. 그런데 ListNode는 단방향으로 설정되어 있어 이전 값을 알 수가 없다. 즉 5의 이전 값이 4인지 알 수 없다. 

    하지만 우리는 위의 분리 과정을 거치면서 second 리스트의 시작 노드가 어딘지 알 수 있다. (slow.next) 따라서 second리스트의 첫 노드부터 시작해서 방향을 반대로 바꾸어 간다.

    // 두 번째 배열 순서 바꾸기 
    ListNode second = slow.next;
    ListNode prev = null;
    slow.next = null;
    while(second != null) {
        ListNode next = second.next;
        second.next = prev;
        prev = second;
        second = next;
    }

    마지막으로 first, second 리스트를 합병해준다.

    // 합병
    ListNode first = head;
    second = prev;
    while(second != null) {
        ListNode tmp = first.next;
        ListNode tmp2 = second.next;
        first.next = second;
        second.next = tmp;
        first = tmp;
        second = tmp2;
    }

     

    🗝 문제풀이

    class Solution {
        public void reorderList(ListNode head) {
            ListNode slow = head;
            ListNode fast = head.next;
    
            while(fast != null && fast.next != null) {
                slow = slow.next;
                fast = fast.next.next;
            }
    
            // 두 번째 배열 순서 바꾸기 
            ListNode second = slow.next;
            ListNode prev = null;
            slow.next = null;
            while(second != null) {
                ListNode next = second.next;
                second.next = prev;
                prev = second;
                second = next;
            }
    
            // 합병
            ListNode first = head;
            second = prev;
            while(second != null) {
                ListNode tmp = first.next;
                ListNode tmp2 = second.next;
                first.next = second;
                second.next = tmp;
                first = tmp;
                second = tmp2;
            }
        }
    }
    저작자표시 비영리 변경금지 (새창열림)
      '알고리즘/LeetCode' 카테고리의 다른 글
      • [LeetCode] Clone Graph (Java)
      • [LeetCode] Insert Interval
      • [LeetCode] Merge Two Sorted Lists (Java)
      • [LeetCode] Linked List Cycle (Java)
      베어_
      베어_
      Today I learned | 문제를 해결하는 개발자

      티스토리툴바