Algorithm & Data Structures/Programers
Lv 3. 풍선 터트리기
Geisha
2024. 12. 4. 16:32
https://school.programmers.co.kr/learn/courses/30/lessons/68646?language=java
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제를 처음 접했을 때 어떤 규칙이 존재하는지를 길게 고민하였다.
좌 우 에서 떨어지면 떨어질수록 최소 비교횟수가 늘어나는 규칙을 찾아내었고
주어진 값이 전체 array 에서 몇 번째로 최소인가를 판단하여 풀이방법을 고민하였다.
고민이 길어지다가 왼쪽 최소, 오른쪽 최소값중 한번이라도 만족한다면 마지막으로 남을 수 있는
가능성이 존재한다는 것을 발견하였고
이를 토대로 왼쪽 최솟값 array, 오른쪽 최솟값 array를 생성하여 set에 넣어줌으로써 문제를 해결.
하지만 시간복잡도와, 공간복잡도면에서 상당히 마음에 들지 않았다.
import java.util.*;
class Solution {
int[] leftMin,rightMin;
public int solution(int[] a) {
int answer = 0;
int size = a.length;
leftMin = new int[size];
rightMin = new int[size];
HashSet<Integer> set = new HashSet<>();
leftMin[0] = a[0];
rightMin[0] = a[size-1];
set.add(leftMin[0]);
set.add(rightMin[0]);
for(int i = 1 ; i < size ; i++){
leftMin[i] = Math.min(leftMin[i-1],a[i]);
rightMin[i] = Math.min(rightMin[i-1],a[size-i-1]);
set.add(leftMin[i]);
set.add(rightMin[i]);
}
return set.size();
}
}
GPT에게 물어본 결과 Set을 활용한 중복제거 자료구조가 Too Much라는 피드백을
받을 수 있었고 아래와 같은 a array 를 활용 for문으로 탐색하며 왼쪽 최소값 arr와
오른쪽 최솟값 arr 중 한번이라도 만족한다면 체크해나가는 식의
피드백 코드는 더욱 시간복잡도와 공간복잡도면에서 효율적임을 배웠다.
import java.util.*;
class Solution {
public int solution(int[] a) {
int size = a.length;
if (size <= 2) return size; // 모든 풍선을 남길 수 있음
int[] leftMin = new int[size];
int[] rightMin = new int[size];
// 왼쪽 최소값 계산
leftMin[0] = a[0];
for (int i = 1; i < size; i++) {
leftMin[i] = Math.min(leftMin[i - 1], a[i]);
}
// 오른쪽 최소값 계산
rightMin[size - 1] = a[size - 1];
for (int i = size - 2; i >= 0; i--) {
rightMin[i] = Math.min(rightMin[i + 1], a[i]);
}
// 생존 가능한 풍선 개수 계산
int count = 0;
for (int i = 0; i < size; i++) {
if (a[i] <= leftMin[i] || a[i] <= rightMin[i]) {
count++;
}
}
return count;
}
}
그리하여 내코드를 위와 같은 형식으로 Set 이 아닌
a[] array를 확인하는 형식으로 수정하였고
광명을 찾을 수 있었다.
import java.util.*;
class Solution {
int[] leftMin,rightMin;
public int solution(int[] a) {
int answer = 0;
int size = a.length;
leftMin = new int[size];
rightMin = new int[size];
leftMin[0] = a[0];
rightMin[size-1] = a[size-1];
for(int i = 1 ; i < size ; i++){
leftMin[i] = Math.min(leftMin[i-1],a[i]);
rightMin[size-i-1] = Math.min(rightMin[size-i],a[size-i-1]);
}
for(int i = 0 ; i < size ; i++){
if(a[i] <= rightMin[i] || a[i] <= leftMin[i])
answer++;
}
return answer;
}
}