ABOUT ME

Today
Yesterday
Total
  • [linked list] palindrome linked list
    Algorithm/LeetCode 2025. 2. 16. 18:50

     Problem

    https://leetcode.com/problems/palindrome-linked-list/description/

     

     Approach & Solution

    공통

    • 리스트의 앞과 뒤의 값을 비교하여 값이 다른 경우 팰린드롬이 아님

     

    방식1) 추가 자료구조 사용

    더보기

    1-1) Stack 사용

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public boolean isPalindrome(ListNode head) {
            Stack<Integer> stack = new Stack<>();
    
            ListNode node = head;
            while (node != null) {
                stack.add(node.val);
                node = node.next;
            }
    
            while (head != null) {
                // 연결 리스트와 스택에서 추출한 값을 비교해 팰린드롬 판별
                if (head.val != stack.pop()) {
                    return false;
                }
                head = head.next;
            }
    
            return true;
        }
    }

     

    1-2) Deque 사용

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public boolean isPalindrome(ListNode head) {
            Deque<Integer> deque = new LinkedList<>();
            // 연결리스트를 deque에 삽입
            ListNode node = head;
            while (node != null) {
                deque.add(node.val);
                node = node.next;
            }
    
            // deque이 모두 비거나 1개가 남을 때(데이터 개수 홀수일 때)까지 비교
            while (!deque.isEmpty() && deque.size() > 1) {
                if (deque.pollFirst() != deque.pollLast()) {
                    return false;
                }
            }
    
            return true;
        }
    }

     

     

    방식2) 기존 자료구조 사용

    더보기
    • 러너 기법 활용
      • 빠른 러너(2칸 씩 이동), 느린 러너(1칸 씩 이동)
    • 느린 러너의 위치를 기준으로 리스트의 중간 지점부터 이후 값에 대한 역순 리스트 생성
    • 기존 리스트와 앞에서부터 비교
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public boolean isPalindrome(ListNode head) {
            // 리스트의 중간 이후 지점부터 역순 연결 리스트를 생성한다.
            // 기존 연결 리스트와 비교한다. (다른 값이 있을 경우 palindrome이 아님)
    
            ListNode fast = head, slow = head;
    
            while (fast != null && fast.next != null) { // fast가 리스트의 끝에 도달했을 때
                fast = fast.next.next; // 2칸 씩 이동
                slow = slow.next; // 1칸 씩 이동
            }
    
            // 중간 값을 넘어가야 하기 때문에 홀수 개인 경우 slow를 한칸 더 이동
            if (fast != null) {
                slow = slow.next;
            }
    
            // slow 값 기준으로 역순 연결 리스트 생성
            ListNode rev = null; // 역순 연결 리스트의 시작 노드
            while (slow != null) {
                ListNode next = slow.next;
                slow.next = rev;
                rev = slow;
                slow = next;
            }
            
            // 기존 리스트와 역순 리스트 원소 비교
            // 한 개라도 다르면 palindrome이 아니므로 false 반환
            while (rev != null) {
                if (head.val != rev.val) {
                    return false;
                }
    
                head = head.next;
                rev = rev.next;
            }
    
            return true;
        }
    }

     

    추가) 러너 기법

    • 러너는 연결 리스트를 순회할 때 2개의 포인터를 동시에 사용하는 기법
      • 한 포인터가 다른 포인터보다 앞서게 하여 병합 지점이나 중간 위치, 길이 등을 판별할 때 유용하게 사용할 수 있음
    • 2개의 포인터는 빠른 러너와 느린 러너로 명칭하고, 빠른 러너는 2 칸씩 느린 러너는 1 칸씩 이동
    • 이때 빠른 러너가 연결 리스트의 끝에 도달하면, 느린 러너는 정확히 연결 리스트의 중간 지점을 가리키게 됨
      • 중간 위치를 찾아내면 전체 길이를 알아낼 수 있고, 여기서부터 값을 비교하거나 뒤집기를 시도하는 등의 활용 가능

    'Algorithm > LeetCode' 카테고리의 다른 글

    댓글

Designed by Tistory.