Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

solved 풍선 터트리기 - 2003.79ms 281MB #237

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions Programmers/풍선터트리기/풍선터트리기_강정훈.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import java.util.*;
class Solution {
private int leftMinValue = Integer.MAX_VALUE;
private int leftSecondMinValue = Integer.MAX_VALUE;
private Set<Integer> visited;
private Queue<Integer> rightQueue;
public int solution(int[] a) {
if(a.length <= 2) {
return a.length;
}
int answer = 0;
visited = new HashSet<>();
rightQueue = new PriorityQueue<>();
for (int baloon : a) {
rightQueue.add(baloon);
}
rightQueue.add(Integer.MAX_VALUE);
rightQueue.add(Integer.MAX_VALUE);
int leftMinValue = Integer.MAX_VALUE;
int leftSecondMinValue = Integer.MAX_VALUE;
for (int baloon : a) {
visited.add(baloon);
int[] rightMinValues = getRightMinValues();
int rightMinValue = rightMinValues[0];
int rightSecondMinValue = rightMinValues[1];
if (canPop(baloon, leftMinValue, leftSecondMinValue, rightMinValue, rightSecondMinValue)) {
answer++;
}
if (leftMinValue > baloon) {
leftSecondMinValue = leftMinValue;
leftMinValue = baloon;
} else if (leftMinValue < baloon && baloon < leftSecondMinValue) {
leftSecondMinValue = baloon;
}
}
return answer;
}
private int[] getRightMinValues() {
int[] rightMinValues = new int[2];
while(true) {
int candidate = rightQueue.peek();
if (visited.contains(candidate)) {
rightQueue.poll();
} else {
if (rightMinValues[0] != 0) {
rightMinValues[1] = candidate;
rightQueue.add(rightMinValues[0]);
break;
}
rightQueue.poll();
rightMinValues[0] = candidate;
}
}
return rightMinValues;
}
private boolean canPop(int baloon, int leftMinValue, int leftSecondMinValue, int rightMinValue, int rightSecondMinValue) {
if (leftMinValue > baloon && rightMinValue > baloon) {
return true;
} else if (leftMinValue > baloon && rightMinValue < baloon) {
return true;
} else if (leftMinValue < baloon && rightMinValue > baloon) {
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import java.util.*;
class Solution {
public int solution(int[] a) {
// answer의 초기값을 1로 하는 이유는 a의 양쪽 끝 값은 항상 터트릴 수 있다.
// 하지만, 아래 로직에서는 양 끝 값은 누락이 된다.
// 대신, left와 right가 겹치는 부분에서 1개가 중복 집계 되기 때문에, 1로 한다.
// while의 조건문을 left < right - 1로 걸어서 겹치는 부분의 중복 집계를 막을 수도 있지만
// a의 길이가 1일 수 있기 때문에, 초기값을 1로하는게 좋아보임.
int answer = 1;
int left = 0;
int right = a.length - 1;
int leftMinValue = a[left];
int rightMinValue = a[right];
while(left < right) {
// 어차피 left나 right 중 한 쪽이 크다면 그쪽 방향에 있는 최솟값은 a[left]나 a[right]와 같거나 낮기 때문
// 그래서 right값이 left보다 크다면, 자신의 오른쪽에 있는 값들만 확인하면 된다.
// left와 right가 중앙으로 오면서 구간별 최솟값이 갱신된다.
// 그래서 투포인터로 적용할 수 있다.
if(a[left] < a[right]) {
if(rightMinValue > a[right-1]) {
rightMinValue = a[right-1];
answer++;
}
right--;
}else {
if(leftMinValue > a[left+1]) {
leftMinValue = a[left+1];
answer++;
}
left++;
}
}
return answer;
}
}