백준
백준[17298]번: 오큰수 ( Java )
하루우울루
2023. 2. 18. 11:49
https://www.acmicpc.net/problem/17298
17298번: 오큰수
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.
www.acmicpc.net
개발환경은 eclipse를 사용했습니다.
Code
import java.util.*;
import java.io.*;
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));
StringTokenizer st;
Stack<Integer> stack = new Stack<>();
int n = Integer.parseInt(br.readLine()); // n의 개수
st = new StringTokenizer(br.readLine()," "); // 문자열 받기
int[] arr = new int[n];
for(int i=0;i<n;i++) // 배열에 저장
{
arr[i] = Integer.parseInt(st.nextToken());
}
for(int i=n-1;i>=0;i--) // 역순열로 계산
{
if(stack.isEmpty()) // 스택이 비어있다면 그값을 넣어주고 문자열 자리에 -1 저장
{
stack.push(arr[i]);
arr[i] = -1;
}
else // 스택이 비어있지 않은 경우
{
if(arr[i] < stack.peek()) // 가장 최근의 스택(가장 왼쪽)이 더 큰 경우 문자열에 저장하고 스택에 push
{
int temp = stack.peek();
stack.push(arr[i]);
arr[i] = temp;
}
else // 가장 최근의 스택(가장 왼쪽)이 작은 경우
{
while(!stack.isEmpty()) // 반복(break로 빠져나올것)
{
stack.pop(); // 제거해서 가장왼쪽이 아닌 그 다음 수를 비교한다
if(stack.isEmpty()) // 다 제거해서 스택이 빈 경우 -1저장 후 break
{
stack.push(arr[i]);
arr[i] = -1;
break;
}
else if(arr[i] < stack.peek()) // 크다면 위와 동일하게 바꾼 후 break
{
int temp = stack.peek();
stack.push(arr[i]);
arr[i] = temp;
break;
}
}
}
}
}
for(int i=0;i<n;i++) // 출력
{
bw.write(arr[i]+" ");
}
bw.close();
}
}
밑에 틀린 코드를 보면 알겠지만 시간초과가 계속 나서 풀이방식을 바꿔야 했다.
풀이방법을 모르겠어서 구글링을 통해서 다른 분의 해결방법을 참고했다.
다른 분들이 푼 방식 보면 어떻게 저렇게 아이디어가 생각날 수 있는 거지?라고 느껴진다...
풀이 방법을 알고 노트로 순서대로 쓰면서 풀었더니 해결되었다.
틀린 코드
import java.util.*;
import java.io.*;
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));
Stack<Integer> stack = new Stack<>();
Stack<Integer> NewStack = new Stack<>();
StringTokenizer st;
int n = Integer.parseInt(br.readLine()); // 수열크기 입력받기
int[] arr = new int[n];
st = new StringTokenizer(br.readLine()," "); // 수열 입력받기
for(int i=0;i<n;i++) // 스택에 추가
{
stack.push(Integer.parseInt(st.nextToken()));
}
for(int i=0;i<n;i++)
{
int max = -1;
arr[i] = stack.peek(); // 뒤에서 부터 뽑기
stack.pop();
for(int j=i-1;j>=0;j--) // 이전의 수들 중 최댓값 찾기
{
if(max < arr[j])
{
if(arr[i] < arr[j])
{
max = arr[j];
break;
}
else
{
max = -1;
}
}
}
NewStack.push(max);
}
for(int i=0;i<n;i++)
{
bw.write(NewStack.peek()+" ");
NewStack.pop();
}
bw.close();
}
}
처음에 이렇게 풀었는데 시간초과가 났다.
애초에 스택을 활용한 풀이가 아니고 입력값을 봤을 때 시간초과가 날 수밖에 없던 것 같다.
문제 풀이 아이디어가 잡힌다면 쉽게 풀 수 있었던 것 같다.