[programmers] Java Lv.2 - H-Index
https://school.programmers.co.kr/learn/courses/30/lessons/42747
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제 설명
H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 위키백과1에 따르면, H-Index는 다음과 같이 구합니다.
어떤 과학자가 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.
어떤 과학자가 발표한 논문의 인용 횟수를 담은 배열 citations가 매개변수로 주어질 때, 이 과학자의 H-Index를 return 하도록 solution 함수를 작성해주세요.
제한사항
- 과학자가 발표한 논문의 수는 1편 이상 1,000편 이하입니다.
- 논문별 인용 횟수는 0회 이상 10,000회 이하입니다.
입출력 예
입출력 예 설명
이 과학자가 발표한 논문의 수는 5편이고, 그중 3편의 논문은 3회 이상 인용되었습니다. 그리고 나머지 2편의 논문은 3회 이하 인용되었기 때문에 이 과학자의 H-Index는 3입니다.
풀이
접근 방식
- 발표한 논문의 인용 횟수를 담은 배열 citations를 `ArrayList<Integer>`로 변환
- 전체 논문 n편에 대해서 H-Index인지 판단
- h번 이상 인용되는 논문이 h편 이상 있어야 한다.
- ➡️ 논문 인용수(.get(인덱스) 값)가 남은 논문 수(n-인덱스)보다 커야 함
int[ ] ➡️ ArrayList<Integer>
// int[] 배열을 ArrayList<Integer>로 변환
ArrayList<Integer> citationList = IntStream.of(citations) // 1. int[]를 IntStream으로 변환
.boxed() // 2. IntStream을 Stream<Integer>로 변환 (박싱)
.sorted() // 3. Stream<Integer>를 오름차순 정렬
.collect(Collectors.toCollection(ArrayList::new)); // 4. Stream<Integer>를 ArrayList로 변환
그런데 다 풀고 생각해보니, 리스트 요소 값을 바꿀것도 아닌데 ArrayList말고 List로 받아도 됐겠다 싶었다.
// int[] 배열을 List<Integer>로 변환
List<Integer> citationList = Arrays.stream(citations) // 1. int[]를 IntStream으로 변환
.boxed() // 2. IntStream을 Stream<Integer>로 변환 (박싱)
.sorted() // 3. Stream<Integer>를 오름차순 정렬
.toList(); // 4. Stream<Integer>를 불변 List로 변환
불변 List는 요소를 추가하거나 제거할 수 없다.
이 문제에서는 요소를 수정할 일이 없으니 ArrayList보다 List를 사용하는게 더 적합해보인다.
풀이 코드
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) throws IOException {
/*
* 어떤 과학자가 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고
* 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.
* => h번 이상 인용되는 논문이 h편 이상 있어야 함.
* => 논문 인용수가 남은 논문 수보다 커야함.
*/
int[] citations = {3, 0, 6, 1, 5};
int answer = 0;
/*
// int[] 배열을 ArrayList<Integer>로 변환
ArrayList<Integer> citationList = IntStream.of(citations) // 1. int[]를 IntStream으로 변환
.boxed() // 2. IntStream을 Stream<Integer>로 변환 (박싱)
.sorted() // 3. Stream<Integer>를 오름차순 정렬
.collect(Collectors.toCollection(ArrayList::new)); // 4. Stream<Integer>를 ArrayList로 변환
*/
// int[] 배열을 List<Integer>로 변환
List<Integer> citationList = Arrays.stream(citations) // 1. int[]를 IntStream으로 변환
.boxed() // 2. IntStream을 Stream<Integer>로 변환 (박싱)
.sorted() // 3. Stream<Integer>를 오름차순 정렬
.toList(); // 4. Stream<Integer>를 불변 List로 변환
for (int i=0; i<citationList.size(); i++) {
// 현재 논문의 인용 횟수 >= 남은 논문 수
if (citationList.get(i) >= citationList.size()-i) {
answer = Math.max(answer, citationList.size()-i);
}
}
System.out.println(answer);
}
}
제출
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
class Solution {
public int solution(int[] citations) {
int answer = 0;
// int[] 배열을 ArrayList<Integer>로 변환
ArrayList<Integer> citationList = IntStream.of(citations) // 1. int[]를 IntStream으로 변환
.boxed() // 2. IntStream을 Stream<Integer>로 변환 (박싱)
.sorted() // 3. Stream<Integer>를 오름차순 정렬
.collect(Collectors.toCollection(ArrayList::new)); // 4. Stream<Integer>를 ArrayList로 변환
for (int i=0; i<citationList.size(); i++) {
// 현재 논문의 인용 횟수 >= 남은 논문 수
if (citationList.get(i) >= citationList.size()-i) {
answer = Math.max(answer, citationList.size()-i);
}
}
return answer;
}
}