강승현입니다
    • 홈
    • 태그
    • 방명록

    카테고리

    • 전체 글 (118)
      • 후기 (38)
        • 경험 (15)
        • SSAFY (9)
        • 코딩테스트 (3)
        • 넥스터즈 (6)
        • 회고 (5)
      • Degrees (2)
      • Tech (33)
      • OnlineJudge (45)
    OnlineJudge

    [프로그래머스] 풍선 터뜨리기 python, java

    CODe_byCODe_·2021. 4. 21. 22:08

     

    문제로이동

     

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

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

    programmers.co.kr


    목차

       


      Python3
      java

      문제 풀이

      접근 방법

      어떤 알고리즘인지 전혀 맥락을 못잡다가 문제 푼 지 35분이 경과되어서 알게 되었습니다.

       

      1. 2개의 임의의 풍선 중 크기가 큰 풍선을 터뜨려야 한다.
      2. 단, 크기가 작은 풍선은 딱 1번만 터뜨릴 수 있다.
      3. 풍선을 터뜨렸다면 풍선의 빈 공간을 다시 채운다(양 옆의 풍선을 당겨준다)
      4. 최후에 1개의 풍선이 남았을 때, 절대 남을 수 없는 풍선의 갯수를 구하자

      DFS인가? 생각했다가 N의 크기를 보고 절대 아니라고 판단했고, O(N)에 끝내야 한다는 것으로 생각을 굳혔습니다.

      다른 측면에서 생각해볼까요?

      어떤 임의의 풍선을 선택하고 왼쪽 또는 오른쪽 풍선 중 하나를 터뜨린다고 생각해 봅시다. (선택한 임의의 풍선은 끝까지 살려 놓겠다고 가정합시다)

       

      이 상황에서 선택한 풍선이 살아 남는 조건은 뭘까요?

      왼쪽 또는 오른쪽에서 당겨지는 풍선이 크거나 또는 1회만 작은 풍선이 온다면 이 풍선은 살아남습니다.

       

      반대로 생각하면 2회 이상 작은 풍선이 온다면 살아 남을 수 없습니다

      구현 방법

      저는 2가지 Array를 사용했습니다.

      1. 왼쪽에서 접근하여 최솟값을 저장 leftMin
      2. 오른쪽에서 접근하여 최솟값을 저장 rightMin

      임의의 a[i]가 leftMin[i], rightMin[i] 두 수보다 크다면 해당 a[i]는 살아남을 수 없습니다.

      그 때 카운팅을 해주고 a의 갯수에서 카운팅한 수를 빼주면 정답을 도출할 수 있습니다.

       

      a -16 27 65 -2 58 -92 -71 -68 -61 -33
      left -16 -16 -16 -16 -16 -92 -92 -92 -92 -92
      right -92 -92 -92 -92 -92 -92 -71 -68 -61 -33

       

      입출력 예제 2번과 동일한 케이스일 때 left와 right는 위와 같습니다.

      붉은색으로 표시 된 a[i] 값들은 left, right에 해당하는 수보다 크기 때문에 살아남을 수 없습니다.

      그렇기 때문에 최종적으로 10-4 연산을 하여 6이라는 정답이 나오게 됩니다.

       


      소스 코드

      Python

      def solution(a):
          answer = 0
          leftMin = [10e9+1]*len(a)
          rightMin = [10e9+1]*len(a)
          leftMin[0]=a[0]
          for i in range(1,len(a)):
              leftMin[i] = min(leftMin[i-1],a[i])
          rightMin[-1]=a[-1]
          for i in range(len(a)-2,-1,-1):
              rightMin[i] = min(rightMin[i+1],a[i])
          for i in range(len(a)):
              if leftMin[i]<a[i] and rightMin[i]<a[i]:
                  answer+=1
          return len(a)-answer

      java

      public int solution(int[] a) {
      	    	int N = a.length;
      	        int answer = 0;	        
      	        int leftMin[] = new int[N];
      	        int rightMin[] = new int[N];
      	        leftMin[0]=a[0];//시작점에 index 0 삽입
      	        for(int i =1;i<N;i++)
      	        	leftMin[i] = Math.min(leftMin[i-1],a[i]);
      	        
      	        rightMin[N-1]=a[N-1];//시작점에 index 끝 삽입
      	        for(int i =N-2;i>=0;i--)
      	        	rightMin[i] = Math.min(rightMin[i+1],a[i]);
      	        
      	        for(int i =0;i<N;i++)
      	        	if(a[i]>leftMin[i] && a[i]>rightMin[i])
      	        		answer++;
      	        return N-answer;
      	    }
      반응형
      저작자표시 비영리 변경금지 (새창열림)
      'OnlineJudge' 카테고리의 다른 글
      • 정올 jungol 2078 13일의 금요일 Java, Python
      • 백준 16724 피리 부는 사나이 python
      • 백준 16954 움직이는 미로 탈출 python
      • SWEA 1953 탈주범 검거 java 풀이
      CODe_
      CODe_
      개발과 관련된 다양한 정보를 몰입감있게 전달합니다.
      최신 글

      티스토리툴바