일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 코딩테스트
- bfs
- 스타트업
- 이직
- 스프링 부트
- 자료구조
- 해결
- 구현
- Java
- dfs
- 스프링
- 주니어
- 백엔드
- 스프링부트
- docker
- 문자열
- IntelliJ
- 구름LEVEL
- 인텔리제이
- 명령어
- 프로그래머스
- spring
- 도커
- 개발자
- 해시맵
- HashMap
- Linux
- HTTP
- 배열
- spring boot
- Today
- Total
마이의 개발 블로그
[프로그래머스] 뒤에 있는 큰 수 찾기 (Java) 본문
접근 방식
이중 반복문으로 테케는 풀렸으나 당연히 시간초과에 걸렸고, 스택으로 풀어야 해결된다는 힌트를 보고 몇 날 며칠을 고민했던 문제다. 다른 사람들의 접근법을 보고난 후에도 로직을 이해하기 위해 노력해야했는데 막상 이해하고나니 너무나 간단한 문제였다. 이런 유형에서 스택을 사용하는 이유는 탐색 도중 구간별 변화를 감지했을 때에만 그 구간에서의 결과값이 도출되기 때문이다. 즉, 구간별 변화(뒤에 나보다 큰 수가 존재하는 것)가 일어나지 않으면 결과값을 도출할 수 없고(-1), 변화가 감지되었을 때에만 탐색된 구간에 대한 결과값을 저장(뒤에 있는 가장 가까운 큰 수를 저장)할 수 있다. 이 문제는 주식 가격이 떨어지지않은 구간의 길이를 구해야하는 주식가격 문제와도 비슷한 유형이라고 볼 수 있는데, 당시에는(꽤 오래전에 풀어놓은 문제임) 이게 왜 스택/큐 문제로 분류되어있는지 이해하지 못하고 반복문으로 풀어냈던 기억이 있다. 이 문제도 스택을 사용하지 않고 반복문으로도 충분히 풀어낼 수 있는 문제라고 판단되어 나중에 반복문으로도 구현해보려고 한다 (아래 추가함).
로직 설명
- 답변 배열 생성 및 -1로 초기화
- numbers 배열을 탐색하며:
1) 구간별 변화가 감지된 경우(현재 숫자가 직전 숫자보다 큰 경우), 해당 구간(스택의 인덱스에 해당하는 숫자가 현재 숫자보다 작은 동안 스택을 연속하여 pop)의 모든 답변을 현재 숫자로 저장
2) 스택에 현재 인덱스 저장(push)
Note
- 작성하고보니 리팩토링으로 좀 더 간결하게 만들 수 있는 문제라는 생각이 든다.
import java.util.*;
class Solution {
public int[] solution(int[] numbers) {
int[] answer = new int[numbers.length];
Arrays.fill(answer, -1);
Stack<Integer> stack = new Stack<>();
for(int i = 0; i < numbers.length; i++){
if(stack.isEmpty() || numbers[i] < numbers[i-1]){
stack.push(i);
}else{
while(!stack.isEmpty() && numbers[i] > numbers[stack.peek()]){
answer[stack.pop()] = numbers[i];
}
stack.push(i);
}
}
return answer;
}
}
2023.3.15 리팩토링
import java.util.*;
class Solution {
public int[] solution(int[] numbers) {
int[] answer = new int[numbers.length];
Arrays.fill(answer, -1);
Stack<Integer> stack = new Stack<>();
for(int i = 0; i < numbers.length; i++){
if(!stack.isEmpty() && numbers[i] > numbers[i-1]){
while(!stack.isEmpty() && numbers[i] > numbers[stack.peek()]){
answer[stack.pop()] = numbers[i];
}
}
stack.push(i);
}
return answer;
}
}
2023.3.15 반복문으로 재작성 (더 빠름)
import java.util.*;
class Solution {
public int[] solution(int[] numbers) {
int[] answer = new int[numbers.length];
for(int i = 0; i < numbers.length - 1; i++){
if(numbers[i + 1] > numbers[i]){
int idx = i;
int biggerNum = numbers[i + 1];
while(idx >= 0 && biggerNum > numbers[idx]){
if(answer[idx] == 0){
answer[idx] = biggerNum;
}
idx--;
}
}
}
for(int i = 0; i < answer.length; i++){
if(answer[i] == 0){
answer[i] = -1;
}
}
return answer;
}
}
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 두 큐 합 같게 만들기 (Java) (0) | 2023.03.20 |
---|---|
[프로그래머스] 주식가격 (Java) (2) | 2023.03.15 |
[프로그래머스] 땅따먹기 (Java) (1) | 2023.03.13 |
[프로그래머스] 대충 만든 자판 (Java) (0) | 2023.03.08 |
[프로그래머스] 유한소수 판별하기 (Java) (0) | 2023.02.22 |