10866 덱 : https://www.acmicpc.net/problem/10866
덱을 이용하여 각 명령을 처리하는 문제입니다.
자바에서 제공하는 LinkedList나 ArrayDeque를 이용하여 풀수 있지만, 직접 구현해보겠습니다.
그리고 동적할당을 위해 resize도 추가해서 구현해볼 예정입니다.
먼저 나만의 덱 ArrayDeque를 생성해줍니다.
class ArrayDeque{
int front;
int rear;
int size;
int[] array;
public ArrayDeque(int capacity){
front = 0;
rear = 0;
size = 0;
array = new int[capacity];
}
}
앞에 값을 추가한다면 front는 앞으로 이동하고, 뒤에 값을 추가한다면 rear를 뒤로 이동시켜줍니다.
front == rear라면 어떠한 값을 가지고 있지않는것이고, rear+1==front라면 해당 배열에 모든 값이 차있다는 뜻이됩니다.
그리고 front는 항상 빈 공간으로 남겨주어야합니다. 실질적인 값은 array[front+1]에 들어있게 됩니다. (그래야 front==end일때 빈값이라고 둘 수 있습니다.)
값을 추가할때, 배열이 가득차있는 경우(front == rear+1) 기존 배열의 크기 2배로 새로운 배열을 생성하여줍니다.
그리고 i를 새로운 배열의 index, j를 기존 배열의 index로 선언하고 새로운 배열을 초기화하여 줍니다.
//i : 새로운 배열 index, j : 기존 배열의 index
for(int i=1, j=front+1;i<=size;i++, j++){
newArray[i] = array[j%arrayCapacity];
}
그리고 난 후 front를 0, rear를 size로 갱신하여 새로운 배열로 덱을 사용하게 됩니다.
값을 추가할때뿐만 아니라, 값을 삭제했을 때도 현재 값이 들어있는 크기(size)가 현재 배열의 1/4의 크기보다 작다면 메모리 크기를 줄여줍니다.
private void resize(int newCapacity){
int arrayCapacity = array.length;
int[] newArray = new int[newCapacity];
for(int i=1, j=front+1;i<=size;i++, j++){
newArray[i] = array[j%arrayCapacity];
}
this.array = newArray;
front = 0;
rear = size;
}
public void push_front(int x){
if((rear+1)%array.length == front) resize(array.length*2);
front = (front-1+array.length)%array.length;
array[(front+1)%array.length] = x;
size++;
}
public void push_back(int x){
if((rear+1)%array.length == front) resize(array.length*2);
rear = (rear+1)%array.length;
array[rear] = x;
size++;
}
public int pop_front(){
if(front==rear) return -1;
if(size-1 < array.length/4) resize(array.length/2);
size--;
front = (front+1)%array.length;
return array[front];
}
public int pop_back(){
if(front==rear) return -1;
if(size-1 < array.length/4) resize(array.length/2);
size--;
int result = array[rear];
rear = ((rear-1)+array.length)%array.length;
return result;
}
public int size(){
return size;
}
public int empty(){
return rear-front == 0 ? 1 : 0;
}
public int front(){
if(front==rear) return -1;
return array[(front+1)%array.length];
}
public int back(){
if(front==rear) return -1;
return array[rear];
}
import java.io.*;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int N = Integer.parseInt(br.readLine());
ArrayDeque deque = new ArrayDeque(10);
StringBuilder sb = new StringBuilder();
for(int i=0;i<N;i++){
StringTokenizer st = new StringTokenizer(br.readLine()," ");
String method = st.nextToken();
int x = 0;
switch(method){
case "push_front":
x = Integer.parseInt(st.nextToken());
deque.push_front(x);
break;
case "push_back":
x = Integer.parseInt(st.nextToken());
deque.push_back(x);
break;
case "pop_front":
sb.append(deque.pop_front()).append("\n");
break;
case "pop_back":
sb.append(deque.pop_back()).append("\n");
break;
case "size":
sb.append(deque.size()).append("\n");
break;
case "empty":
sb.append(deque.empty()).append("\n");
break;
case "front":
sb.append(deque.front()).append("\n");
break;
case "back":
sb.append(deque.back()).append("\n");
break;
}
}
bw.write(sb.toString());
bw.flush();
bw.close();
}
static class ArrayDeque{
int front;
int rear;
int size;
int[] array;
public ArrayDeque(int capacity){
front = 0;
rear = 0;
size = 0;
array = new int[capacity];
}
public void push_front(int x){
if((rear+1)%array.length == front) resize(array.length*2);
front = (front-1+array.length)%array.length;
array[(front+1)%array.length] = x;
size++;
}
public void push_back(int x){
if((rear+1)%array.length == front) resize(array.length*2);
rear = (rear+1)%array.length;
array[rear] = x;
size++;
}
public int pop_front(){
if(front==rear) return -1;
if(size-1 < array.length/4) resize(array.length/2);
size--;
front = (front+1)%array.length;
return array[front];
}
public int pop_back(){
if(front==rear) return -1;
if(size-1 < array.length/4) resize(array.length/2);
size--;
int result = array[rear];
rear = ((rear-1)+array.length)%array.length;
return result;
}
public int size(){
return size;
}
public int empty(){
return rear-front == 0 ? 1 : 0;
}
public int front(){
if(front==rear) return -1;
return array[(front+1)%array.length];
}
public int back(){
if(front==rear) return -1;
return array[rear];
}
private void resize(int newCapacity){
int arrayCapacity = array.length;
int[] newArray = new int[newCapacity];
for(int i=1, j=front+1;i<=size;i++, j++){
newArray[i] = array[j%arrayCapacity];
}
this.array = newArray;
front = 0;
rear = size;
}
}
}