본문 바로가기

Algorithm/Programers - Java

[프로그래머스(Java)] 전국 대회 선발 고사 / PriorityQueue, Stream ( range, filter, box, sorted, reduce, get)

 

Level. 0

 

문제

0번부터 n - 1번까지 n명의 학생 중 3명을 선발하는 전국 대회 선발 고사를 보았습니다.
등수가 높은 3명을 선발해야 하지만, 개인 사정으로 전국 대회에 참여하지 못하는 학생들이 있어 참여가 가능한 학생 중 등수가 높은 3명을 선발하기로 했습니다.

각 학생들의 선발 고사 등수를 담은 정수 배열 rank와 전국 대회 참여 가능 여부가 담긴 boolean 배열 attendance가 매개변수로 주어집니다.
전국 대회에 선발된 학생 번호들을 등수가 높은 순서대로 각각 a, b, c번이라고 할 때 10000 × a + 100 × b + c를 return 하는 solution 함수를 작성해 주세요.

* 제한사항
- 3 ≤ rank의 길이 = attendance의 길이 ≤ 100
- rank[i]는 i번 학생의 선발 고사 등수를 의미합니다.
- rank의 원소는 1부터 n까지의 정수로 모두 서로 다릅니다.
- attendance[i]는 i번 학생의 전국 대회 참석 가능 여부를 나타냅니다.
   attendance[i]가 true라면 참석 가능, false면 참석 불가능을 의미합니다.
- attendance의 원소 중 적어도 3개는 true입니다.

 

풀이

import java.util.Arrays;
import java.util.ArrayList;

class Solution {
    // 선발 고사 등수를 담은 정수 배열 rank
    // 전국 대회 참여 가능 여부가 담긴 boolean 배열 attendance
    public int solution(int[] rank, boolean[] attendance) {
        int[] sorted = rank.clone();
        ArrayList<Integer> list = new ArrayList<>();
        Arrays.sort(sorted);
        for(int i=0; i<sorted.length; i++){
            for(int j=0; j<rank.length; j++){
                if(sorted[i] == rank[j] && attendance[j]){
                    list.add(j);
                    break;
                }
            }
            if(list.size() == 3) break;
        }
        
        return list.get(0) * 10000 + list.get(1) * 100 + list.get(2);
    }
}

 


다른 풀이 1 - Stream

import java.util.Comparator;
import java.util.stream.IntStream;

class Solution {
    public int solution(int[] rank, boolean[] attendance) {
        return IntStream.range(0, rank.length)
                .filter(i -> attendance[i])
                .boxed()
                .sorted(Comparator.comparing(i -> rank[i]))
                .limit(3L)
                .reduce((current, next) -> current * 100 + next)
                .get();
    }
}

 

  1.  range() : IntStream의 range는 범위에 맞게 순차적으로 증가하는 IntStream을 반환해 준다.
                      -> rank 길이만큼 스트림을 생성한다. 
  2.  filter() : attendance로 필터링. 스트림 요소를 순회하면서 특정 조건을 만족하는 요소로 구성된 새로운 스트림을 반환한다.
  3.  boxed() : Stream로 변환. int, long, double 요소를 Integer, Long, Double 요소로 박싱하여 스트림을 생성한다. 
  4.  sorted() : Comparator.comparing()을 사용하여 rank의 값을 기준으로 정렬
  5.  limit() : 낮은 숫자 3개만 데이터를 가져와 새로운 스트림 생성
  6.  reduce() : reduce()는 스트림의 원소들에 누적 계산을 수행하여 결과값을 리턴하는 메서드이다.
                       -> 100을 곱하고 다음 항목을 더하는 누적계산을 수행한다. 
  7.  get() : optional 객체의 값을 반환한다. 객체의 값이 null이 아닐 경우에만 사용한다.
                  -> int타입의 값을 반환한다. 

 

 

다른 풀이 2 - PriorityQueue

import java.util.PriorityQueue;

class Solution {
    public int solution(int[] rank, boolean[] attendance) {

        PriorityQueue<Integer> que = new PriorityQueue<>((a, b) -> rank[a] - rank[b]);
        for (int i = 0; i < attendance.length; i++) {
            if (attendance[i])
                que.add(i);
        }

        return que.poll() * 10000 + que.poll() * 100 + que.poll();
    }
}

 

PriorityQueue - 우선순위 큐

  • 우선순위큐는 먼저 들어온 순서대로 데이터가 나가는 것이 아닌 우선순위를 먼저 결정하고 그 우선순위가 높은 데이터가 먼저 나가는 자료구조이다. 

https://school.programmers.co.kr/learn/courses/30/lessons/181851

 

프로그래머스

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

programmers.co.kr

https://velog.io/@pppp0722/Java-Comparator.comparing%EC%9D%B4%EB%9E%80

 

Java Comparator.comparing()이란?

Comparator의 comparing()을 사용하면 List의 원소들을 비교하여 정렬하는 것을 간단한 방식으로 구현할 수 있게 해준다. 우선 comparing()을 사용하지 않는 방법을 살펴보자. List를 정렬하는 방법들 예를

velog.io

https://www.geeksforgeeks.org/intstream-range-java/

 

IntStream range() in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org