99클럽 코테 스터디 10일차 TIL 이중우선순위큐

2024. 8. 1. 00:25·스터디/99클럽 코테 스터디 TIL
목차
  1. 📝 문제
  2. 🔥 시도해본 접근 방식
  3. 1️⃣ 첫번째 시도
  4. 2️⃣ 두번째 시도
  5.  ✨ 성공 코드

📝 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

🔥 시도해본 접근 방식

본 문제는 입력으로 들어온 문자열 배열을 해석하여

1. 숫자를 삽입

2. 최솟값 제거

3. 최댓값 제거

위 명령을 큐를 사용하여 수행하면서 [최댓값, 최솟값]배열을 출력하면 될 것이라고 생각하고 접근하였다.

 

PriorityQueue를 사용하면 최소값을 제거하는 작업은 단순히 poll()을 해주면 되지만,

최댓값을 제거하는 작업은 효율적인 방법이 떠오르지 않아 우선 새로운 PriorityQueue를 선언해 기존 PriorityQueue에서 size - 1 까지 값을 뽑아내어 넣어주는 방식으로 적용하였다.

 

1️⃣ 첫번째 시도

import java.util.PriorityQueue;

class Solution {
    public static int[] solution(String[] operations) {
        // 힙 선언
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        for (String o : operations) {
            // 큐에서 최대값을 삭제한다.
            if (!pq.isEmpty() && o.equals("D 1")) {
                PriorityQueue<Integer> newPq = new PriorityQueue<>();

                for (int i = 0; i < pq.size() - 1; i++) {
                    newPq.offer(pq.poll());
                }

                pq = newPq;
            }
            // 큐에서 최소값을 삭제한다.
            else if (!pq.isEmpty() && o.equals("D -1")) {
                pq.poll();
            }
            // 큐에 숫자를 삽입힌다.
            else if (o.startsWith("I")) {
                int i = Integer.parseInt(o.substring(2));
                pq.offer(i);
            }
        }

        int size = pq.size();
        int[] answer = new int[]{0, 0};
        for (int i = 0; i < size; i++) {
            int value = pq.poll();

            if (i == 0) {
                answer[1] = value;
            } else if (i == n - 1) {
                answer[0] = value;
            }
        }

        return answer;
    }
}

위와 같이 코드를 작성하여 제출하였지만 테스트 케이스 3개에서 통과되지 못하고 실패하였다.

코드를 실행 하였을때, 입력으로 받은 문자열 배열대로 숫자 입력, 제거 동작이 문제없이 잘 작동하는 것으로 보여지는데 어떤것을 놓치고 있는지 출력을 프린트 해보았더니

입력이 ["I 1", "I 3", "I 5", "I 7", "I 9", "D -1", "D -1", "D 1", "I 2", "D 1", "D 1"]와 같을 때 "D 1" 부분에서 [5, 7, 9] -> [5] 와같이 변하는 결함을 발견하였고 for문의 pq.size()가 반복됨에 따라 값이 변하는 문제가 있음을 깨달았다.

2️⃣ 두번째 시도

import java.util.PriorityQueue;

class Solution {
    public static int[] solution(String[] operations) {
        // 힙 선언
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        for (String o : operations) {
            // 큐에서 최대값을 삭제한다.
            if (!pq.isEmpty() && o.equals("D 1")) {
                PriorityQueue<Integer> newPq = new PriorityQueue<>();
                
                int size = pq.size();
                for (int i = 0; i < size - 1; i++) {
                    newPq.offer(pq.poll());
                }

                pq = newPq;
            }
            // 큐에서 최소값을 삭제한다.
            else if (!pq.isEmpty() && o.equals("D -1")) {
                pq.poll();
            }
            // 큐에 숫자를 삽입힌다.
            else if (o.startsWith("I")) {
                int i = Integer.parseInt(o.substring(2));
                pq.offer(i);
            }
        }

        int size = pq.size();
        int[] answer = new int[]{0, 0};
        for (int i = 0; i < size; i++) {
            int value = pq.poll();

            if (i == 0) {
                answer[1] = value;
            } else if (i == n - 1) {
                answer[0] = value;
            }
        }

        return answer;
    }
}

따라서 다음과 같이 코드를 수정하였고 다시 제출해보았지만 결과는 동일하였다.

긴 시간 고민에도 원인을 찾을 수 없어 반례 하나를 찾아보았고, 원인을 알 수 있었다.

만약 큐의 사이즈가 1일 때 내 코드는 항상 [0, 최솟값]을 리턴할 것이다 하지만 이 경우에는 최댓값과 최솟값이 같은 값으로 리턴되어야 했다는 것을 깨닫고 코드를 보완하였다.

 ✨ 성공 코드

import java.util.PriorityQueue;

class Solution {
    public static int[] solution(String[] operations) {
        // 힙 선언
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        for (String o : operations) {
            // 큐에서 최대값을 삭제한다.
            if (!pq.isEmpty() && o.equals("D 1")) {
                PriorityQueue<Integer> newPq = new PriorityQueue<>();

                int size = pq.size();
                for (int i = 0; i < size - 1; i++) {
                    newPq.offer(pq.poll());
                }

                pq = newPq;
            }
            // 큐에서 최소값을 삭제한다.
            else if (!pq.isEmpty() && o.equals("D -1")) {
                pq.poll();
            }
            // 큐에 숫자를 삽입힌다.
            else if (o.startsWith("I")) {
                int i = Integer.parseInt(o.substring(2));
                pq.offer(i);
            }
        }

        int size = pq.size();
        int[] answer = new int[]{0, 0};
        
        for (int i = 0; i < size; i++) {
            int value = pq.poll();
            
            if (i == 0) {
                answer[1] = value;

                // 큐의 사이즈가 1일 수도 있으므로 최댓값도 갱신해준다.
                answer[0] = value;
            } else if (i == size - 1) {
                answer[0] = value;
            }
        }

        return answer;
    }
}

10 회차 까지 문제풀이를 하면서 문제 자체에 대한 이해도가 조금 부족하다는 느낌을 받았다.

다음 부터는 문제에 대해 부족함 없이 이해하기 위한 노력을 많이 기울여야 할 것 같다.

 

클릭하여 좋은 풀이 보기

사실 내 풀이는 문제의 힌트인 이중우선순위큐의 목적과는 맞지 않은 풀이였다고 생각되는데 다른사람의 풀이를 보고 개인적으로 목적에 가장 부합한 풀이라고 생각하는 풀이는 다음과 같다.

import java.util.Collections;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
class Solution {
    public int[] solution(String[] arguments) {
        MidV q = new MidV();

        for(int i = 0; i < arguments.length; i++){
            String[] commend = arguments[i].split(" ");

            int v = Integer.parseInt(commend[1]);
            if(commend[0].equals("I")){
                q.push(v);
            }else{
                switch (v){
                    case 1 : q.removeMax();
                    break;
                    case -1: q.removeMin();
                    break;
                }
            }
        }


        int[] aw = new int[]{q.getMaxValue(),q.getMinValue()};

        return aw;
    }
}

class MidV{
    private PriorityQueue<Integer> leftHeap;
    private PriorityQueue<Integer> rightHeap;

    public MidV(){
        leftHeap = new PriorityQueue<>(10,Collections.reverseOrder());//최대값;
        rightHeap = new PriorityQueue<>();//최소값
    }


    public void push(int v){
        leftHeap.add(v);
    }

    public void removeMax(){

        while(!rightHeap.isEmpty()){
            leftHeap.add(rightHeap.poll());
        }

        leftHeap.poll();
    }

    public void removeMin(){

        while(!leftHeap.isEmpty()){
            rightHeap.add(leftHeap.poll());
        }

        rightHeap.poll();
    }

    public int getMaxValue(){

        if(leftHeap.size() == 0 && rightHeap.size() == 0)
            return 0;

        while(!rightHeap.isEmpty()){
            leftHeap.add(rightHeap.poll());
        }

        return leftHeap.peek();
    }

    public int getMinValue(){

        if(leftHeap.size() == 0 && rightHeap.size() == 0)
            return 0;

        while(!leftHeap.isEmpty()){
            rightHeap.add(leftHeap.poll());
        }

        return rightHeap.peek();
    }

}

'스터디 > 99클럽 코테 스터디 TIL' 카테고리의 다른 글

99클럽 코테 스터디 12일차 TIL H-Index  (0) 2024.08.03
99클럽 코테 스터디 11일차 TIL 카드 뭉치  (0) 2024.08.01
99클럽 코테 스터디 9일차 TIL 더 맵게  (0) 2024.07.31
99클럽 코테 스터디 8일차 TIL 기능개발  (0) 2024.07.29
99클럽 코테 스터디 7일차 TIL 하노이의 탑  (0) 2024.07.29
  1. 📝 문제
  2. 🔥 시도해본 접근 방식
  3. 1️⃣ 첫번째 시도
  4. 2️⃣ 두번째 시도
  5.  ✨ 성공 코드
'스터디/99클럽 코테 스터디 TIL' 카테고리의 다른 글
  • 99클럽 코테 스터디 12일차 TIL H-Index
  • 99클럽 코테 스터디 11일차 TIL 카드 뭉치
  • 99클럽 코테 스터디 9일차 TIL 더 맵게
  • 99클럽 코테 스터디 8일차 TIL 기능개발
Been
Been
BeenBeen 님의 블로그입니다.
  • Been
    Been
    Been
  • 전체
    오늘
    어제
    • 분류 전체보기 (60)
      • 언어 (0)
        • Kotlin (0)
      • 안드로이드 (17)
      • iOS (3)
      • Git (1)
      • 스터디 (39)
        • 알고리즘 문제 풀이 (1)
        • 99클럽 코테 스터디 TIL (38)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    nsl
    RecyclerView
    maxWidth
    깃
    WRITE EXTERNAL
    아이폰
    IOS
    Git
    FragmentStateAdapter
    NSR
    EditText
    TIL
    Coroutines
    객체변환
    자바
    Android
    개발자취업
    언더라인 제거
    java
    밑줄제거
    Androiod
    AndroidID
    쓰기권한
    debugRuntimeClasspath
    풀이실패
    리싸이클러뷰
    항해99
    안드로이드
    코딩테스트준비
    99클럽
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Been
99클럽 코테 스터디 10일차 TIL 이중우선순위큐
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.