-
반응형
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; } /* 안되는 경우 = 왼쪽편의 최솟값과 오른쪽편의 최솟값 두개보다 큰경우 */
반응형'문제풀이 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 로또의 최고 순위와 최저 순위 (0) 2021.05.09 [프로그래머스] 게임 맵 최단거리 (0) 2021.03.30 [프로그래머스] 섬 연결하기 (0) 2021.03.21 [프로그래머스] 2 x n 타일링 (0) 2021.03.21 [프로그래머스] 등굣길 (0) 2021.03.06 댓글