문제풀이/프로그래머스

[프로그래머스] 풍선 터트리기

Hyeon-Uk 2021. 3. 26. 03:29
반응형

programmers.co.kr/learn/courses/30/lessons/68646

 

코딩테스트 연습 - 풍선 터트리기

[-16,27,65,-2,58,-92,-71,-68,-61,-33] 6

programmers.co.kr


 

-풀이-

먼저 a의 길이를 보았을때 ,O(N*N)은 불통과할게 뻔해보이므로 O(NlogN) 이나 O(N)으로 풀 수 있는 방법이 있는지 생각해보았다.

그러자 전체 개수에서 안되는 개수를 빼면 되는데, 안되는 경우를 생각해보니

해당 i번째 인덱스 원소 기준 좌측의 최솟값보다 크고, 우측의 최솟값보다 크면 안된다.

 

문제에서 주어진 "인접한 두 풍선 중에서 번호가 더 작은 풍선을 터트리는 행위는 최대 1번만 할 수 있습니다" 를 마지막에 적용을 시킨다고 해보자. 

 

i번째 인덱스의 값을 5라고 하고,

좌측에서 마지막까지 살아남은 수(최솟값)을 -5라하고, 우측에서 마지막까지 살아남은 수(최솟값)을 -10이라 하자. 

이런 경우가 된다면,

1) -5와 5중 작은 번호를 터트리면 5가 살아남고, 5와 -10이 있으면 -10이 살아남으니 x

2) -5와 5중 큰번호를 터트려버리면 5가 살지 못하므로 x

3) 5와 -10중 작은 번호를 터트리면 5가 살아남고, -5와 5가 있으면 -5가 살아남으니 x

4) 5와 -10중 큰번호를 터트려버리면 5가 살지 못하므로 x

 

따라서 이런경우는 절대 살아남지 못한다.

 

그래서 처음 O(N)시간을 투자하여 i번째기준 좌측의 최솟값과, 우측의 최솟값을 저장해둔뒤, 배열을 돌며 위의 해당하는 경우를 빼주면 답이 나온다.

 

-시간 복잡도-

처음 좌,우측의 최솟값을 저장하는 로직은 O(N)이 걸리고, 풍선의 생존여부를 결정하는 로직도 O(N)이 되므로,

최종적으로O(N)이 된다.

 

-코드-

 

#include <string>
#include <vector>
#include<algorithm>
#include<iostream>
using namespace std;

int solution(vector<int> a) {
    int answer = 0;
    int n=a.size();
    answer=n;
    vector<int> left(n),right(n);
    
    //O(N);
    left[0]=a[0];
    right[n-1]=a[n-1];
    for(int i=1;i<n;i++){
        left[i]=min(left[i-1],a[i]);
        right[n-i-1]=min(right[n-i],a[n-i]);
    }
    
    for(int i=1;i<n-1;i++){
        if(left[i]<a[i]&&right[i]<a[i]) answer--;
    }

    return answer;
}

/*
안되는 경우 = 왼쪽편의 최솟값과 오른쪽편의 최솟값 두개보다 큰경우
*/

 

반응형