
프로그래머스 코딩테스트 Lv. 1 Java로 31부터 40까지 풀기 (최신순 정렬 기준)
이 문제에는 표준 입력으로 두 개의 정수 n과 m이 주어집니다.별(*) 문자를 이용해 가로의 길이가 n, 세로의 길이가 m인 직사각형 형태를 출력해보세요.
입력
5 3
출력
*****
*****
*****
반복문으로 세로만큼 출력하게 하고, n만큼 repeat 시키면 될 듯.
import java.util.Scanner;
class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
for (int i = 0; i < b; i++) {
System.out.println("*".repeat(a));
}
}
}
다른 사람 코드에서는 sb가 호평을 받았는데 이거도 배워둬야 겠음.
import java.util.Scanner;
import java.util.stream.IntStream;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
StringBuilder sb = new StringBuilder();
IntStream.range(0, a).forEach(s -> sb.append("*"));
IntStream.range(0, b).forEach(s -> System.out.println(sb.toString()));
}
}
주어진 숫자 중 3개의 수를 더했을 때 소수가 되는 경우의 개수를 구하려고 합니다. 숫자들이 들어있는 배열 nums가 매개변수로 주어질 때, nums에 있는 숫자들 중 서로 다른 3개를 골라 더했을 때 소수가 되는 경우의 개수를 return 하도록 solution 함수를 완성해주세요.
| nums | result |
|---|---|
| [1,2,3,4] | 1 |
| [1,2,7,6,4] | 4 |
에라토스테네스로 소수인지 아닌지 판별한 다음에 삼중 중첩 반복문으로 배열에서 3개를 더하면 될 듯.
import java.util.*;
class Solution {
public boolean[] primeArr;
public int solution(int[] nums) {
int answer = 0, sum;
Arrays.sort(nums);
primeArr = new boolean[nums[nums.length-1]+nums[nums.length-2]+nums[nums.length-3]+1];
is_prime(primeArr.length);
for (int i = 0; i < nums.length-2; i++) {
for (int j = i+1; j < nums.length-1; j++) {
for (int k = j+1; k < nums.length; k++) {
sum = nums[i] + nums[j] + nums[k];
if (!primeArr[sum]) answer++;
}
}
}
return answer;
}
public void is_prime(int num) {
if (num < 1) return;
primeArr[0] = primeArr[1] = true;
for (int i = 2; i <= Math.sqrt(num); i++) {
if (primeArr[i] == true) continue;
for (int j = i * i; j < primeArr.length; j += i) {
primeArr[j] = true;
}
}
}
}
삼중 이상의 중첩은 좋지 않은 코드라곤 하는데 이 경우에는 아예 피할 수는 없는 듯함.
S사에서는 각 부서에 필요한 물품을 지원해 주기 위해 부서별로 물품을 구매하는데 필요한 금액을 조사했습니다. 그러나, 전체 예산이 정해져 있기 때문에 모든 부서의 물품을 구매해 줄 수는 없습니다. 그래서 최대한 많은 부서의 물품을 구매해 줄 수 있도록 하려고 합니다.
물품을 구매해 줄 때는 각 부서가 신청한 금액만큼을 모두 지원해 줘야 합니다. 예를 들어 1,000원을 신청한 부서에는 정확히 1,000원을 지원해야 하며, 1,000원보다 적은 금액을 지원해 줄 수는 없습니다.
부서별로 신청한 금액이 들어있는 배열 d와 예산 budget이 매개변수로 주어질 때, 최대 몇 개의 부서에 물품을 지원할 수 있는지 return 하도록 solution 함수를 완성해주세요.
| d | budget | result |
|---|---|---|
| [1,3,2,5,4] | 9 | 3 |
| [2,2,3,3] | 10 | 4 |
부서가 신청한 금액만큼을 모두 지원해 줘야 하며, 최대한 많은 부서에 지원이 가능해야 하므로, d를 오름차순 정렬한 뒤, 차감되는 만큼 result 카운팅과 budget 차감하면 될듯.
import java.util.*;
class Solution {
public int solution(int[] d, int budget) {
int answer = 0;
Arrays.sort(d);
for (int i = 0; i < d.length; i++) {
if (d[i] <= budget) {
budget -= d[i];
answer++;
} else break;
}
return answer;
}
}
굿. 근데 내일부터 난이도가 높아지는 것 같다. 좀 무섭다.
네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.
n인 정사각형 배열 형태로, 각 칸은 "공백"(" ") 또는 "벽"("#") 두 종류로 이루어져 있다.1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.
네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.
입력으로 지도의 한 변 크기 n 과 2개의 정수 배열 arr1, arr2가 들어온다.
n ≦ 16arr1, arr2는 길이 n인 정수 배열로 주어진다.x를 이진수로 변환했을 때의 길이는 n 이하이다. 즉, 0 ≦ x ≦ 2 - 1을 만족한다. n원래의 비밀지도를 해독하여 '#', 공백으로 구성된 문자열 배열로 출력하라.
| 매개변수 | 값 |
|---|---|
| n | 5 |
| arr1 | [9, 20, 28, 18, 11] |
| arr2 | [30, 1, 21, 17, 28] |
| 출력 | ["#####","# # #", "### #", "# ##", "#####"] |
| 매개변수 | 값 |
|---|---|
| n | 6 |
| arr1 | [46, 33, 33 ,22, 31, 50] |
| arr2 | [27 ,56, 19, 14, 14, 10] |
| 출력 | ["######", "### #", "## ##", " #### ", " #####", "### # "] |
10진수 값을 2진수로 바꾼다음에 만약 하나라도 1인 값이 있다면 그 자리는 #로, 아니면 공백으로 놓으면 될듯.
class Solution {
public String[] solution(int n, int[] arr1, int[] arr2) {
String[] answer = new String[n];
String arr1Binary, arr2Binary, result;
for (int i = 0; i < n; i++) {
result = "";
arr1Binary = String.format("%0" + n + "d", Long.parseLong(Long.toBinaryString(arr1[i])));
arr2Binary = String.format("%0" + n + "d", Long.parseLong(Long.toBinaryString(arr2[i])));
for (int j = 0; j < n; j++) {
if (arr1Binary.charAt(j) == '1' || arr2Binary.charAt(j) == '1') result = result.concat("#");
else result = result.concat(" ");
}
answer[i] = result;
}
return answer;
}
}
속도는 굉장히 느림.
class Solution {
public String[] solution(int n, int[] arr1, int[] arr2) {
String[] answer = new String[n];
String temp;
for(int i = 0 ; i < n ; i++){
temp = String.format("%16s", Integer.toBinaryString(arr1[i] | arr2[i]));
temp = temp.substring(temp.length() - n);
temp = temp.replaceAll("1", "#");
temp = temp.replaceAll("0", " ");
answer[i] = temp;
}
return answer;
}
}
이 코드가 제일 괜찮은 거 같음.
처음에 16자리로 포맷한 다음에 앞쪽에 남는 자릿수는 잘라내기 → 0과 1은 비교 대신 바로 replaceAll로 바꿔치기
카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.
S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수¹ , 점수² , 점수³)으로 계산된다.*), 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고)*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.
"점수|보너스|[옵션]"으로 이루어진 문자열 3세트.예) 1S2D*3T
3번의 기회에서 얻은 점수 합계에 해당하는 정수값을 출력한다.
예) 37
| 예제 | dartResult | answer | 설명 |
|---|---|---|---|
| 1 | 1S2D*3T | 37 | 1¹ 2 + 2² 2 + 3³ |
| 2 | 1D2S#10S | 9 | 1² + 2¹ * (-1) + 10¹ |
| 3 | 1D2S0T | 3 | 1² + 2¹ + 0³ |
| 4 | 1S*2T*3S | 23 | 1¹ 2 2 + 2³ * 2 + 3¹ |
| 5 | 1D#2S*3S | 5 | 1² (-1) 2 + 2¹ * 2 + 3¹ |
| 6 | 1T2D3D# | -4 | 1³ + 2² + 3² * (-1) |
| 7 | 1D2S3T* | 59 | 1² + 2¹ 2 + 3³ 2 |
문자열이니 split으로 한글자씩 나눠서 그 글자가 SDT인지, *#인지, 숫자인지를 검사한 후에 그에 대응하는 식을 넣어주면 될듯.
import java.util.*;
class Solution {
public int solution(String dartResult) {
// scoreArrIdx = 결과 저장할 배열 인덱스
// lengthMinusOne = 위 인덱스에서 하나 뺀거
// lengthMinusTwo = 위 인덱스에서 두개 뺀거
int scoreArrIdx = 0, lengthMinusOne, lengthMinusTwo, answer = 0;
// scoreArr = 결과 저장할 배열
int[] scoreArr = new int[3];
// dartResultArr = dartResult split한 배열
String[] dartResultArr = dartResult.split("");
// str = 반복문에서 dartResultArr[i]를 담당해줄 애
String str = "";
for (int i = 0; i < dartResultArr.length; i++) {
// 변수 정리
str = dartResultArr[i];
lengthMinusOne = scoreArrIdx - 1;
lengthMinusTwo = scoreArrIdx - 2;
// 숫자가 나오면 scoreArr 배열에 바로 넣어주기
if (str.matches("[0-9]")) {
scoreArr[scoreArrIdx] = scoreArr[scoreArrIdx] * 10 + Integer.parseInt(str);
continue;
}
// *나 #가 나오면 그에 따른 값 변화 적용하기
if (str.equals("*")) {
scoreArr[lengthMinusOne] = scoreArr[lengthMinusOne] * 2;
if (scoreArrIdx == 1) continue;
scoreArr[lengthMinusTwo] = scoreArr[lengthMinusTwo] * 2;
continue;
}
else if (str.equals("#")) {
scoreArr[lengthMinusOne] = scoreArr[lengthMinusOne] * -1;
continue;
}
// S의 경우 1제곱이므로 패스
// D나 T가 나오면 각각 2제곱, 3제곱
if (str.equals("D")) scoreArr[scoreArrIdx] = (int)Math.pow(scoreArr[scoreArrIdx], 2);
else if (str.equals("T")) scoreArr[scoreArrIdx] = (int)Math.pow(scoreArr[scoreArrIdx], 3);
// 숫자나 *, #가 나오면 continue로 인해 접근할 수 없으므로
// SDT가 나오면 이 부분을 거치도록 함. => SDT가 나오는 부분에 인덱스 이동
scoreArrIdx++;
}
// 결과 합산
for (int score : scoreArr) {
answer += score;
}
return answer;
}
}
원래 반환값을 stream으로 처리하려고 했는데 거기서 너무 시간을 많이 잡아먹어서 그냥 반복문으로 해결함.
수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.
| participant | completion | return |
|---|---|---|
| ["leo", "kiki", "eden"] | ["eden", "kiki"] | "leo" |
| ["marina", "josipa", "nikola", "vinko", "filipa"] | ["josipa", "filipa", "marina", "nikola"] | "vinko" |
| ["mislav", "stanko", "mislav", "ana"] | ["stanko", "ana", "mislav"] | "mislav" |
두 배열을 정렬해서 순서마다 비교해주고 안 맞는 구간이 있으면 출력되도록 하면 될듯.
import java.util.*;
class Solution {
public String solution(String[] participant, String[] completion) {
Arrays.sort(participant);
Arrays.sort(completion);
for (int i = 0; i < completion.length; i++) {
if (!participant[i].equals(completion[i])) return participant[i];
}
return participant[participant.length-1];
}
}
import java.util.*;
class Solution {
public String solution(String[] participant, String[] completion) {
String answer = "";
HashMap<String, Integer> hm = new HashMap<>();
for (String player : participant) hm.put(player, hm.getOrDefault(player, 0) + 1);
for (String player : completion) hm.put(player, hm.get(player) - 1);
for (String key : hm.keySet()) {
if (hm.get(key) != 0){
answer = key;
}
}
return answer;
}
}
동명이인으로 인해 getOrDefault를 사용함.
hm이 Arrays.sort보다 빠르므로 시간 복잡도를 고려하면 밑 방법으로 사용하면 됨.
배열 array의 i번째 숫자부터 j번째 숫자까지 자르고 정렬했을 때, k번째에 있는 수를 구하려 합니다.
예를 들어 array가 [1, 5, 2, 6, 3, 7, 4], i = 2, j = 5, k = 3이라면
배열 array, [i, j, k]를 원소로 가진 2차원 배열 commands가 매개변수로 주어질 때, commands의 모든 원소에 대해 앞서 설명한 연산을 적용했을 때 나온 결과를 배열에 담아 return 하도록 solution 함수를 작성해주세요.
| array | commands | return |
|---|---|---|
| [1, 5, 2, 6, 3, 7, 4] | [[2, 5, 3], [4, 4, 1], [1, 7, 3]] | [5, 6, 3] |
문제에서 시키는대로 배열 자르고 정렬하고 k 값에 따라서 값 뽑아오면 될 듯.
import java.util.*;
class Solution {
public int[] solution(int[] array, int[][] commands) {
int[] answer = new int[commands.length];
for (int i = 0; i < commands.length; i++) {
int[] subArr = Arrays.copyOfRange(array, commands[i][0]-1, commands[i][1]);
Arrays.sort(subArr);
answer[i] = subArr[commands[i][2]-1];
}
return answer;
}
}
이렇게 푸는게 맞나봐용
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다.
1번 수포자가 찍는 방식: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...2번 수포자가 찍는 방식: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ...3번 수포자가 찍는 방식: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...
1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution 함수를 작성해주세요.
| answers | return |
|---|---|
| [1,2,3,4,5] | [1] |
| [1,3,2,4,2] | [1,2,3] |
학생들이 찍는 방식은 정해져 있으면서 문제 수에 따라 그만큼 반복할 것임.
이제 배열을 하나 만들어서 학생이 답을 맞출때마다 +1해서 가장 높은 점수를 가진 사람을 출력하도록 하면 됨.
import java.util.*;
class Solution {
public int[] solution(int[] answers) {
int[] student1 = {1, 2, 3, 4, 5};
int[] student2 = {2, 1, 2, 3, 2, 4, 2, 5};
int[] student3 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
int count1 = 0, count2 = 0, count3 = 0, ansInt, arrMax;
int[] correct = new int[3];
for (int i = 0; i < answers.length; i++) {
if (count1 >= student1.length) count1 = 0;
if (count2 >= student2.length) count2 = 0;
if (count3 >= student3.length) count3 = 0;
ansInt = answers[i];
if (ansInt == student1[count1]) correct[0]++;
if (ansInt == student2[count2]) correct[1]++;
if (ansInt == student3[count3]) correct[2]++;
count1++;
count2++;
count3++;
}
arrMax = Arrays.stream(correct).max().getAsInt();
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
if (arrMax == correct[i]) list.add(i+1);
}
return list.stream().mapToInt(Integer::intValue).toArray();
}
}
stream()에서 시간을 다 잡아먹는다고 함
그리고 코드를 간추릴 수 있을 것 같아서 간추려봄.
import java.util.*;
class Solution {
public int[] solution(int[] answers) {
int[] student1 = {1, 2, 3, 4, 5};
int[] student2 = {2, 1, 2, 3, 2, 4, 2, 5};
int[] student3 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
int ansInt, arrMax;
int[] correct = new int[3];
for (int i = 0; i < answers.length; i++) {
ansInt = answers[i];
if (ansInt == student1[i%student1.length]) correct[0]++;
if (ansInt == student2[i%student2.length]) correct[1]++;
if (ansInt == student3[i%student3.length]) correct[2]++;
}
arrMax = Math.max(correct[0], Math.max(correct[1], correct[2]));
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
if (arrMax == correct[i]) list.add(i+1);
}
int[] result = new int[list.size()];
for (int i = 0; i < result.length; i++) {
result[i] = list.get(i);
}
return result;
}
}
1) 채점하는 반복문에서 length를 통해 배열 인덱스를 조정할 수 있으므로 count1, count2, count3과 관련된 코드 제거함
2) 최대값을 구하는 부분에서 stream() 사용을 제거하고 Math.max를 사용하도록 함. 학생이 3명밖에 없어서 가능한 일.
3) 리스트를 만든다음, 그 크기와 같은 배열을 만들어 값을 옮김. 여기서도 stream()은 제외시킴.
메모리 부분은 솔직히 장담 못하지만 속도 부부은 2~4배가량 빨라졌음.
점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.
전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.
| n | lost | reserve | return |
|---|---|---|---|
| 5 | [2, 4] | [1, 3, 5] | 5 |
| 5 | [2, 4] | [3] | 4 |
| 3 | [3] | [1] | 2 |
우선 명심할 것은 여벌 체육복을 가지고 있는 학생도 도둑 맞았을 수 있다는 점.
그래서 처음에 배열 하나를 만들어서 체육복 수를 저장해둬야 할 듯.
그리고 앞 뒤로 조사해서 체육복이 있으면 빌려주도록 하면 될 듯.
1번 학생부터 가져오지 못했을 수 있으니 체육복을 빌려주는 원칙은 바로 위 번호가 아래 번호에게 빌려주는 것을 우선 구하고 다음에 아래 번호가 빌려주는 걸 계산하면 될 듯.
class Solution {
public int[] student;
public int solution(int n, int[] lost, int[] reserve) {
student = new int[n];
for (int i = 0; i < lost.length; i++) { student[lost[i]-1]--; }
for (int i = 0; i < reserve.length; i++) { student[reserve[i]-1]++; }
for (int i = 0; i < n; i++) {
student[i]++;
if (student[i] != 0) continue;
if (i != 0) borrowBottom(i);
if (i != n - 1) borrowTop(i);
}
int answer = 0;
for (int i = 0; i < n; i++) {
if (student[i] != 0) answer++;
}
return answer;
}
public void borrowBottom(int idx) {
if (student[idx-1] == 2 && student[idx] == 0) {
student[idx]++;
student[idx-1]--;
}
return;
}
public void borrowTop(int idx) {
if (student[idx+1] == 2 && student[idx] == 0) {
student[idx]++;
student[idx+1]--;
}
return;
}
}
중간에 에러 뜬게 있었는데 만약에 체육복 보유 상황이 2 0 2라고 할 때 2번 학생이 1번 학생에게 체육복을 빌렸다면 3번학생에게는 빌리지 못하도록 검사하는 구간이 필요했음.
그래서 borrowBottom과 borrowTop에 자신의 체육복이 0인 상태에서만 빌리도록 함.
함수 나누는게 중독 됐나 싶다. 그래도 보기는 좋아보임.
슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다.
이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.
전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.
1 이상 500 이하의 자연수이다.1 이상 200,000 이하이다.1 이상 N + 1 이하의 자연수가 담겨있다.N + 1 은 마지막 스테이지(N 번째 스테이지) 까지 클리어 한 사용자를 나타낸다.0 으로 정의한다.| N | stages | result |
|---|---|---|
| 5 | [2, 1, 2, 6, 2, 4, 3, 3] | [3,4,2,1,5] |
| 4 | [4,4,4,4,4] | [4,1,2,3] |
스테이지 인덱스와 함께 실패율을 담을 해시맵을 만들어서 정렬해주면 될듯.
import java.util.*;
class Solution {
public int[] solution(int N, int[] stages) {
int[] answer = new int[N];
HashMap<Integer, Double> failureRate = new HashMap<>();
int challengePlayer = 0, failurePlayer = 0, max = 0;
for (int i = 0; i < N; i++) {
challengePlayer = 0;
failurePlayer = 0;
for (int j = 0; j < stages.length; j++) {
if (stages[j] < i + 1) continue;
challengePlayer++;
if (stages[j] == i + 1) failurePlayer++;
}
if (challengePlayer == 0) {
failureRate.put(i+1, 0.0);
continue;
}
failureRate.put(i+1, (double)failurePlayer/challengePlayer);
}
List<Integer> list = new ArrayList<>(failureRate.keySet());
Collections.sort(list, (o1, o2) -> Double.compare( failureRate.get(o2), failureRate.get(o1) ) );
return list.stream().mapToInt(Integer::intValue).toArray();
}
}
KeySet(): key 값만 반환함.
대신 저걸로 하면 시간이 너무 느리게 나옴.
import java.util.*;
class Solution {
public int[] solution(int N, int[] stages) {
int[] answer = new int[N];
double[] failureRate = new double[N];
int challengePlayer = 0, failurePlayer = 0, max = 0;
for (int i = 0; i < N; i++) {
challengePlayer = 0;
failurePlayer = 0;
for (int j = 0; j < stages.length; j++) {
if (stages[j] < i + 1) continue;
challengePlayer++;
if (stages[j] == i + 1) failurePlayer++;
}
if (challengePlayer == 0) {
failureRate[i] = 0.0;
continue;
}
failureRate[i] = (double)failurePlayer/challengePlayer;
}
for (int i = 0; i < N; i++) {
answer[i] = i+1;
}
int temp = 0;
double tempDouble = 0.0;
for (int i = 0; i < N - 1; i++) {
for (int j = i + 1; j < N; j++) {
if (failureRate[i] < failureRate[j] || (failureRate[i] == failureRate[j] && answer[i] > answer[j])) {
tempDouble = failureRate[i];
failureRate[i] = failureRate[j];
failureRate[j] = tempDouble;
temp = answer[i];
answer[i] = answer[j];
answer[j] = temp;
}
}
}
return answer;
}
}
그래서 속도가 그나마 줄어들도록 해봄.
굳이 해시맵 사용했다가 stream 사용하지 않도록 해시맵도 배열로 변경함.
1) 이제 슬슬 어려워진다.