백준 2812 크게 만들기 java
1. 문제에 대하여 📦
N개의 자릿수가 있는 수에서 K개의 자릿수를 지운다. 이때 가장 크게 만들 수 있는 수를 출력하라.
2. 코드가 나오기까지 🛠️
KEY WORD: 그리디 알고리즘, 스택K개를 뺄 수 있으므로, 총 선택해야할 숫자는
먼저 주어진 문자열을
N-K 개이다. 이때 STACK을 활용한다.먼저 주어진 문자열을
int [] 배열 형태로 담는다. (해당 배열을 nums라 하겠다.)- nums[0]를 stack에 담는다.
- 이제 nums[1]부터 nums[N-1]까지 순회하며 다음을 반복한다. (지시자 = i)
- stack의 top보다 num[i]가 더 클 경우 stack.pop()을 한다.
- 1번을 stack.top >= nums[i]가 될때까지 혹은 pop() 횟수가 K번을 넘지 않을 떄까지 반복한다.
- 이후 nums[i]를 stack에 넣는다.
- 만약 pop 횟수가 K번이 되었다면 더 이상 pop은 안되므로 이후의 숫자는 stack의 size()가 N-K가 될 때까지 그냥 집어넣는다.
이렇게 일방 통행으로 최대한 큰값으로 자릿수를 최신화하는 풀이가 되는 이유는 '같은 자릿수에서는 비교적 숫자가 큰 값이 존재하는게 전체 숫자를 더 크게 만들기 때문.' 이다.
(1) 시간복잡도 분석 ⏳
N번만 순회하면 문제가 풀린다. K번의 POP과 N-K번의 Push가 들어가긴 하지만 원소 하나 조회당 일어나는 것이 아니라 전체 과정에서 각각 K번, N-K번만 일어나므로 무시해도 되는 수준이다.
따라서 최악의 시간복잡도는 $O(N)$
따라서 최악의 시간복잡도는 $O(N)$
3. 코드 🌐
import java.util.*; import java.io.*; // 2812번 크게 만들기 public class Main { static int N, K; static int [] nums; static int [] stack; 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()); nums = new int [N]; stack = new int [N-K]; char [] temp = br.readLine().toCharArray(); for(int i = 0; i < temp.length; i++){ nums[i] = temp[i] - '0'; } int cnt = 0; int top = 0; stack[top] = nums[top]; for(int i = 1 ; i < N; i++){ int now = nums[i]; while (cnt < K && top >= 0 && stack[top] < now) { top--; cnt++; } top++; if(top >= N-K) break; else stack[top] = now; // System.out.printf("top=%d, cnt=%d %s\\n", top, cnt, Arrays.toString(stack)); } StringBuilder ans = new StringBuilder(); for(int i = 0; i < stack.length; i++){ ans.append(stack[i]); } System.out.printf("%s", ans); }}
4. 트러블 슈팅 or 배운 점📝
(1) 아이디어 못 떠올림
아이디어 싸움인 문제였다. 떠올리면 쉽게 풀고 아니면 틀린다.
처음에 슬라이딩 윈도우를 써서 값 하나 빼고 새로운 수를 1의 자릿수로 붙였을 때랑, 그냥 놔뒀을 때 차이를 비교하려고 했는데, N= 500,000 인 관계로 시간 초과가 예상되어 사용하지 못했다.
처음에 슬라이딩 윈도우를 써서 값 하나 빼고 새로운 수를 1의 자릿수로 붙였을 때랑, 그냥 놔뒀을 때 차이를 비교하려고 했는데, N= 500,000 인 관계로 시간 초과가 예상되어 사용하지 못했다.