// 1. 일반 큐 자료형 선언
Queue<자료형> 이름 = new LinkedList<>();
// 2. 오름차순 우선순위 큐 선언 (값의 크기 순서로 출력 -> 오름차순)
PriorityQueue<자료형> 이름 = new PriorityQueue<>();
// 3. 내림차순 우선순위 큐 선언 (값의 크기 순서로 출력 -> 내림차순)
Queue<자료형> 이름 = new LinkedList<>(Collections.reverseOrder());
add()
→ 값 추가peek()
→ 값 확인poll()
→ 값 출력 후 삭제element()
→ peek 과 비슷, 하지만 값이 없을 경우 오류 출력size()
→ 자료구조의 크기 출력isEmpty()
→ 값 비어있는지 확인 true/false(1) 백준 2164
문제 이해
슈도 코드
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(bf.readLine());
Queue<Integer> queue = new LinkedList<>();
// 큐에 값 저장
for (int i = 1; i <= n; i++) {
queue.add(i);
}
while (queue.size() > 1) {
queue.poll();
int temp = queue.element();
queue.poll();
queue.add(temp);
}
System.out.println(queue.element());
}
}
후입선출 LIFO → 제일 마지막에 넣은 값이 먼저 나온다.
맨 위에 있는 값을 top
이라 한다.
선언
Stack<자료형> 이름 = new Stack<>();
백준 1874 문제 (스택으로 오름차순 수열 만들기)
관련 함수
push()
→ 맨 위 top 에 값 추가pop()
→ 맨 위 top 값 출력 후 빼기(1) 백준 1874
N 을 입력 받아 해당 크기만큼 순열을 입력받는다, arr 배열에 순열 저장.
답 출력을 위한 StringBuffere sf 초기화
Stack 자료구조를 생성하고, num = 1 초기화 (오름차순을 위함)
if( 순열의 값이 num 보다 크거나 같다면 )
else { if (num보다 작다 )→ pop 을 통해 값 꺼냄, “NO” 출력
else { num == 순열값 이니까, sf에 “-” 추가
e. StringBuffer 출력
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(bf.readLine());
int[] arr = new int[n];
boolean result = true;
for (int i = 0; i < n; i++) {
int temp = Integer.parseInt(bf.readLine());
arr[i] = temp;
}
StringBuffer sf = new StringBuffer();
Stack<Integer> stack = new Stack<>();
int num = 1;
for (int i = 0; i < arr.length; i++) {
int su = arr[i];
if (su >= num) {
while (su >= num) {
stack.push(num++);
sf.append("+\n");
}
stack.pop();
sf.append("-\n");
} else {
int a = stack.pop();
if (a > su) {
System.out.println("NO");
result = false;
break;
} else {
sf.append("-\n");
}
}
}
if(result) System.out.println(sf.toString());
}
}
(2) 백준 17298
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(bf.readLine());
Stack<Integer> stack = new Stack<>();
StringTokenizer st = new StringTokenizer(bf.readLine());
int[] arr = new int[N];
for (int i = 0; i < N; i++) {
int a = Integer.parseInt(st.nextToken());
arr[i] = a;
stack.add(a);
}
for (int i = 0; i < arr.length; i++) {
int max = 0;
while (stack.size() > i + 1) {
int temp = stack.pop();
if (arr[i] < temp) {
max = temp;
}
}
if (max != 0) {
System.out.print(max + " ");
} else {
System.out.println("-1 ");
}
for (int j = i + 1; j < arr.length; j++) {
stack.add(arr[j]);
}
}
}
}
이와 같이 풀었으나 시간 복잡도가 N제곱이라 시간 초과로 실패하였다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(bf.readLine());
Stack<Integer> stack = new Stack<>();
int[] arr = new int[N];
int[] nge = new int[N]; // 오큰수를 저장할 배열
StringTokenizer st = new StringTokenizer(bf.readLine());
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
// 오큰수 계산
for (int i = 0; i < N; i++) {
while (!stack.isEmpty() && arr[stack.peek()] < arr[i]) {
nge[stack.pop()] = arr[i];
}
stack.push(i);
}
// 남은 스택에 대해 오큰수가 없는 경우 -1로 처리
while (!stack.isEmpty()) {
nge[stack.pop()] = -1;
}
// 결과 출력
for (int i = 0; i < N; i++) {
System.out.print(nge[i] + " ");
}
}
}
이진 탐색은 중간값을 계속 찾아 나아가는 방식이다. 위 배열처럼 배열 값 중 중간 값을 찾고 찾고자 하는 값을 찾아간다.
예를 들어 10을 찾고자 할 때
1. 중간 값인 27을 기준으로 왼쪽과 오른쪽 두 개의 노드가 생김
2. 찾고자 하는 값인 10이 왼쪽 노드에 있으므로 왼쪽에서 중간 값을 찾음
이와 같은 과정을 10이 나올 때까지 반복한다.
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
// 중간 요소가 타겟과 같은지 확인
if (arr[mid] == target)
return mid;
// 중간 요소보다 타겟이 작으면 왼쪽 부분 탐색
else if (arr[mid] < target)
left = mid + 1;
// 중간 요소보다 타겟이 크면 오른쪽 부분 탐색
else
right = mid - 1;
}
// 탐색 실패 시 -1 반환
return -1;
}