[JAVA] 백준 2812번 크게 만들기 자바 풀이
스택을 활용한 그리디 문제입니다.
📚 문제
🔗 문제 링크
📖 문제 설명
- N자리 숫자가 주어졌을 때, 여기서 숫자 K개를 지워서 얻을 수 있는 가장 큰 수를 구하는 문제
- 입력으로 주어진 숫자에서 K개의 수를 제거했을 때 얻을 수 있는 가장 큰 수를 출력
🔍 입력 조건
- 첫째 줄에 N과 K가 주어짐 (1 ≤ K < N ≤ 500,000)
- 둘째 줄에 N자리 숫자가 주어짐
- 입력되는 숫자는 모두 자연수임
🔍 출력 조건
- 입력으로 주어진 숫자에서 K개의 수를 지웠을 때 얻을 수 있는 가장 큰 수를 출력
🧩 문제 분류
- 알고리즘: 그리디(Greedy), 스택
- 자료구조: 스택(Stack), 문자열
- 난이도: GOLD III
🚀 접근 방법
- 스택을 사용하여 숫자들을 관리
- 현재 숫자가 스택의 top에 있는 숫자보다 크다면, K가 남아있는 한 pop
- 최종적으로 N-K 자리의 가장 큰 수를 구함
💻 구현
/**
* BAEKJOON ONLINE JUDGE
* 문제 이름 : 크게 만들기
* 문제 번호 : 2812
* 난이도 : GOLD III
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.stream.Collectors;
public class Main {
static int N, K;
static char[] nums;
// 구현
public static String simulate(){
Stack<Integer> stack = new Stack<>();
// 각 글자 탐색
for (int i = 0; i < nums.length; i++){
// int로 변환
int curr = Character.getNumericValue(nums[i]);
// 현재 값과 stack top에 있는 값을 비교해서 더 큰 값이 맨 앞에 들어가도록 pop
while (!stack.isEmpty() && stack.peek() < curr && K != 0){
stack.pop();
K--;
}
// 현재 값은 항상 stack에 넣음
stack.push(curr);
}
// K개가 다 지워지지 않았다면, K개 지워질 때 까지 pop
while( K > 0 ){
stack.pop();
K--;
}
// stack을 string으로 매핑 (최대 길이가 500000)
String result = stack.stream()
.map(String::valueOf)
.collect(Collectors.joining());
return result;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
String s = br.readLine();
nums = s.toCharArray();
System.out.println(simulate());
}
}
⏱ 시간 복잡도
- O(N): 각 숫자는 최대 한 번씩만 스택에 들어가고 나옴
💾 공간 복잡도
- O(N): 스택에 최대 N개의 숫자가 저장될 수 있음
📝 회고
- 이런 유형의 문제는 스택을 활용하면 효율적으로 해결할 수 있다는 걸 배움