[LeetCode#641] Design Circular Deque

2024. 8. 5. 14:38·Algorithm/문제풀이

❒ Description


제목 Design Circular Deque
링크 https://leetcode.com/problems/design-circular-deque/description/
자료구조 선형 (배열 / 이중 연결 리스트)
시간복잡도 O(1)


이번 문제는 이중 연결 리스트로 Circular-Deque를 구현하는 문제였다.

근데 사실 이중 연결 리스트로  Circular-Deque를 구현하면 원형의 이점을 살릴 수 없다.

실제로 원형의 이점을 살리기 위해선 이 문제를 연결리스트가 아닌 배열로 풀이해야 한다.

따라서 이번 문제는 이중 연결 리스트와 배열 모두 구현 해볼 것이다.

 

 

 

❒ Solution


1. 이중 연결 리스트 (Doubly-Linked List)

더보기
public class MyCircularDeque {

    public static class ListNode {
        ListNode next;
        ListNode prev;
        int val;

        public ListNode(int val) {
            this.val = val;
        }
    }

    int currentSize;
    int size;
    ListNode head;
    ListNode tail;


    public MyCircularDeque(int k) {
        this.head = null;
        this.tail = null;
        this.currentSize = 0;
        this.size = k;
    }

    public boolean insertFront(int value) {
        if (isFull()) {
            return false;
        }
        ListNode newNode = new ListNode(value);
        currentSize++;
        if(isEmpty()){
            head=tail=newNode;
            return true;
        }
        newNode.next = head;
        head.prev = newNode;
        head = newNode;
        return true;
    }

    public boolean insertLast(int value) {
        if (isFull()) {
            return false;
        }
        ListNode newNode = new ListNode(value);
        currentSize++;
        if (isEmpty()) {
            head=tail=newNode;
            return true;
        }
        newNode.prev = tail;
        tail.next = newNode;
        tail = newNode;
        return true;
    }

    public boolean deleteFront() {
        if(isEmpty()) {
            return false;
        }
        currentSize--;
        if (head == tail) {
            head = tail = null;
            return true;
        }
        head = head.next;
        head.prev = null;
        return true;
    }

    public boolean deleteLast() {
        if (isEmpty()) {
            return false;
        }
        currentSize--;
        if (head == tail) {
            head = tail = null;
            return true;
        }
        tail = tail.prev;
        tail.next = null;
        return true;
    }

    public int getFront() {
        if(isEmpty()) {
            return -1;
        }
        return head.val;
    }

    public int getRear() {
        if(isEmpty()) {
            return -1;
        }
        return tail.val;
    }

    public boolean isEmpty() {
        return head == null || tail == null;
    }

    public boolean isFull() {
        return currentSize == size;
    }
}

 

 

2. 배열 (Array)

더보기
public class MyCircularDeque {
    int front = -1;
    int rear = -1;
    int size;
    int[] cq;

    public MyCircularDeque(int k) {
        this.size = k;
        this.cq = new int[k];
    }

    public boolean insertFront(int value) {
        if (isFull()) {
            return false;
        }    
        if (isEmpty()) {
            front = 0;
            rear = 0;
            cq[front] = value;
        } else if (front == 0) {
            front = size - 1;
            cq[front] = value;
        } else {
            front--;
            cq[front] = value;
        }
        return true;
    }

    public boolean insertLast(int value) {
        if (isFull()) {
            return false;
        }
        if (isEmpty()) {
            front = 0;
            rear = 0;
            cq[rear] = value;
        } else if (rear == size - 1) {
            rear = 0;
            cq[rear] = value;
        } else {
            rear++;
            cq[rear] = value;
        }
        return true;
    }

    public boolean deleteFront() {
        if (isEmpty()) {
            return false;
        }
        if (rear == front) {
            front = -1;
            rear = -1;
        } else if (front == size - 1) {
            front = 0;
        } else {
            front ++;
        }
        return true;
    }

    public boolean deleteLast() {
        if (isEmpty()) {
            return false;
        }
        if (front == rear) {
            front = -1;
            rear = -1;
        } else if (rear == 0) {
            rear = size - 1;
        } else {
            rear--;
        }
        return true;
    }

    public int getFront() {
        if (isEmpty())
            return -1;
        return cq[front];
    }

    public int getRear() {
        if (isEmpty())
            return -1;
        return cq[rear];
    }

    public boolean isEmpty() {
        return front == -1 && rear == -1;
    }

    public boolean isFull() {
        return front == (rear + 1) % size;
    }
}

배열을 통한 Circular-DQ는 inner static 클래스도 필요 없었고, 훨씬 simple 한 느낌이였다.

메소드 별로 코드 분석을 해보자.

 

1. insertFront(value) 

public boolean insertFront(int value) {
    if (isEmpty()) {
    	front = 0;
        rear = 0;
        cq[front] = value;
    } else if (front == 0) {
    	front = size - 1;
        cq[front] = value;
    } else {
    	front--;
        cq[front] = value;
    }
    return true;
}

 

Q가 비어있는 경우 front와 rear를 각각 +1 해준다. 이 경우 front와 bear는 같은 인덱스를 바라 본다.

Q[0]이 이미 front 인 경우에는 front를 마지막 index로 옮겨 줘야한다. 따라서 front에 `size - 1`을 할당한다.

그 외의 경우 front에서 -1을 해준단.

 

2. insertFront(value) 

public boolean insertLast(int value) {
    if (isEmpty()) {
    	front = 0;
      	rear = 0;
        cq[rear] = value;
    } else if (rear == size - 1) {
   		rear = 0;
        cq[rear] = value;
    } else {
    	rear++;
        cq[rear] = value;
    }
}

 

`rear == size - 1` 즉, rear가 마지막 인덱스를 가리키고 있을 땐 index 0으로 변경해줘야 한다.

 

3. isFull()

public boolena isFull() {
    return front == (rear + 1) % size;
}

rear가 갈 수 있는 다음 위치가 front와 동일하다면 Q가 가득찼다고 간주한다.

 

 

 

'Algorithm > 문제풀이' 카테고리의 다른 글

[LeetCode#973] K Closest Points to Origin  (0) 2024.08.08
[LeetCode#23] Merge K sorted Lists  (0) 2024.08.06
[LeetCode#622] Design Circular Queue  (0) 2024.08.04
[LeetCode#739] Daily Temperatures  (0) 2024.07.31
[LeetCode#92] Reverse Linked List II  (0) 2024.07.28
'Algorithm/문제풀이' 카테고리의 다른 글
  • [LeetCode#973] K Closest Points to Origin
  • [LeetCode#23] Merge K sorted Lists
  • [LeetCode#622] Design Circular Queue
  • [LeetCode#739] Daily Temperatures
gilbert9172
gilbert9172
gilbert9172 님의 블로그 입니다.
  • gilbert9172
    バックエンド
    gilbert9172
  • 전체
    오늘
    어제
    • All Categories (173)
      • 우테코 7기 (21)
        • 1주차 (8)
        • 2주차 (5)
        • 3주차 (6)
      • Langauge (4)
        • Java (3)
        • Kotlin (1)
      • Back-End (13)
        • SpringBoot (1)
        • Trouble Shooting (0)
        • Setup & Configuration (1)
        • SQL (3)
        • Redis (8)
      • Architecture (6)
        • Multi Module (1)
        • DDD (5)
      • CS (30)
        • Data Structure (6)
        • Operating System (0)
        • Network (12)
        • Database (10)
        • Design Pattern (2)
      • Algorithm (78)
        • 내용 정리 (18)
        • 문제풀이 (60)
      • DevOps (6)
        • AWS (5)
        • Git (1)
      • Front-End (1)
        • Trouble Shooting (1)
      • Project (6)
        • 페이스콕 (6)
      • Book (7)
        • 이벤트 기반 마이크로서비스 구축 (6)
        • 친절한 SQL 튜닝 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    binarysearch
    sliding-window
    Two-Pointer
    부분단조성
    greedy
    오블완
    Back-Tracking
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
gilbert9172
[LeetCode#641] Design Circular Deque
상단으로

티스토리툴바