https://programmers.co.kr/learn/courses/30/lessons/42841

 

코딩테스트 연습 - 숫자 야구

[[123, 1, 1], [356, 1, 0], [327, 2, 0], [489, 0, 1]] 2

programmers.co.kr

 

해결 방안

문제에서 주어진 문장으로 전체 숫자 경우 도출

1. 전체 경우는 (000~999)라고 생각하였으며 그 중 서로 다른 3자리 숫자 이므로 (123~987)로 범위를 줄일 수 있었음
또한 같은 숫자와 0이 들어간 숫자가 나온 경우 continue 해줘서 가능한 전체 숫자를 정해줌 (위와 같이 전체 경우가 주어짐)

2. 전체 경우의 수를 돌면서 baseball 이차원 배열에 담긴 전체 수와 비교하여 strike 수와 ball 수가 모두 같으면 가능한 답이 되므로 answer++ 해줌
=> 도중 flag를 두어 strike 수와 ball 수가 틀린 경우 break를 해주고 flag에 따라 answer++를 해줌

 

코드

import java.util.*;

// 숫자 야구

class Solution {
    public int solution(int[][] baseball) {
        // 세자리 수 가능한 답의 갯수
        int answer = 0;
        
        int[] answerNum = new int[3];
        int[] baseballNum = new int[3];
        int strike, ball;
        boolean flag;
        
        // 세자리수 전체 경우 돌면서 baseball 전체 행이랑 비교
        // 전체 경우: 1~9 3개의 임의 숫자(서로다른 3자리 숫자)(123~987)
        for(int i=123; i<=987; i++){
            // 각 자리 수
            answerNum[0] = i/100;
            answerNum[1] = (i%100)/10;
            answerNum[2] = i%10;
            
            // 0 나오면 제외
            if(answerNum[0] == 0 || answerNum[1] == 0 || answerNum[2] == 0)
                continue;
            
            // 같은 숫자 나온 경우 제외
            if(answerNum[0] == answerNum[1] || answerNum[1] == answerNum[2] || answerNum[0] == answerNum[2])
                continue;
            
            flag = true;
            // baseball 한 행씩 비교해서 전체 baseball 행 다 맞으면 answer++
            for(int j=0; j< baseball.length; j++){
                
                strike = 0;
                ball = 0;
                
                // baseball 각 자릿수
                baseballNum[0] = baseball[j][0]/100;
                baseballNum[1] = (baseball[j][0]%100)/10;
                baseballNum[2] = baseball[j][0]%10;
                
                // answerNum과 baseballNum 스트라이크 체크
                for(int k=0; k<3; k++){
                    if(answerNum[k] == baseballNum[k])
                        strike++;
                }
                
                // answerNum과 baseballNum 볼 체크
                for(int k=0; k<3; k++){
                    for(int x=0; x<3; x++){
                        if(k != x){
                            if(answerNum[k] == baseballNum[x])
                                ball++;
                        }
                    }
                }
                
                // baseball에 저장되 있는 스트라이크, 볼 수와 우리가 체크한 strike, ball 수 비교
                if(baseball[j][1] == strike && baseball[j][2] == ball){
                    continue;
                }
                else{
                    flag = false;
                    break;
                }   
            }
            if(flag)
                answer++;
        }
        
        return answer;
    }
}

 

https://programmers.co.kr/learn/courses/30/lessons/42842

 

코딩테스트 연습 - 카펫

Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 노란색으로 칠해져 있고 테두리 1줄은 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다. Leo는 집으로 돌아와서 아까 본 카펫의 노란색과 ��

programmers.co.kr

첫 번째 풀이

카펫의 중앙 부분의 가로, 세로 길이를 이용하여 완전 탐색을 이용해 문제를 풀었음

 

해결 방안


1. 문제에 주어진 input으로 테두리(갈색) 갯수와 중앙(노란색) 갯수를 알 수 있고 이 것을 통해 카페의 전체 total 갯수를 알 수 있다고 생각함 

2. 전체 갯수는 (yellow 부분의 가로+2) * (yellow 부분의 세로+2)와 같다고 생각함
=> 테두리(갈색)가 한 줄 이므로 전체 가로 길이 = 왼쪽, 오른쪽 테두리(yellow 부분의 가로+2), 전체 세로 길이 = 위, 아래 테두리(yellow 부분의 세로+2)

3. yellow 갯수도 (yellow 부분의 가로) * (yellow 부분의 세로) 와 같음

4. 두 가지 조건(2,3)에 맞는 yellow의 가로,세로 길이를 찾기 위해 이중 반복문을 이용하여 가로 길이에 따른 세로 길이를 +1씩 해주면서 완전 탐색함

5. 답을 찾는데 걸리는 시간을 줄이기 위해 세로 길이를 늘려주면서 (카펫의 가로 길이 >= 세로 길이) 조건을 만족하지 않을때 break 함

 

코드

// 카펫
// 중앙은 노란색, 테두리 1줄이 갈색인 카펫
// 카펫 가로길이 >= 세로길이
class Solution {
    public int[] solution(int brown, int yellow) {
        // 카펫 가로, 세로 크기
        int[] answer = new int[2];
        
        int total = brown + yellow;
        
        // yellow
        int yWidth = 0;
        int yHeight = 0;
        
        // 전체 갯수 = (옐로 부분 가로 + 2) * (옐로 부분 세로 + 2)
        while(total != (yWidth+2) * (yHeight+2)){
            yWidth++;
            yHeight = 0;

            // yellow 갯수 = 옐로 부분 가로 * 옐로 부분 세로 
            while(yellow != yWidth * yHeight){
            	yHeight++ ;              
                // 세로 길이가 가로길이보다 길면 break
                if(yHeight >= yWidth) {
                	break;                	
                }
            }   
        }
        
        // yellow의 약수들 다 구한다음
        answer[0] = 2 + yWidth;
        answer[1] = 2 + yHeight;

        return answer;
    }
}

 

두 번째 풀이

 

해결 방안

1. 전체 크기를 total에 저장해주고 x(가로의 크기)를 total부터 1까지 줄여나가는 반복문을 이용하였다.
이때 total이 x(가로)로 나눠지면 y(세로)를 구해주고 구해진 x(가로), y(세로)를 이용하여 brown이 될 부분을 구해서 실제 brown 값과 비교해서 값이 같으면 그때 x(가로), y(세로) 값이 정답이므로 break해준다.

코드

// 카펫
// 중앙 노란색 테두리 1줄은 갈색
// 노란색 갈색 갯수 기억
// 카펫의 가로 길이는 세로 길이와 같거나 세로 길이보다 김
class Solution {
    public int[] solution(int brown, int yellow) {
        int[] answer = {0,0};
        int x = 0; // 가로
        int y = 0; // 세로
        int total = brown + yellow;
        
        int tempBrown;
        for(int i=total; i>0; i--){
            x = i;
            
            // total이 x로 나눠지면 y 구함
            if(total % x == 0){
                y = total/x;
                
                tempBrown = (2*x + 2*y) -4;
                if(tempBrown == brown)
                    break;
            }
            else{
                continue;
            }
        }
        
        answer[0] = x;
        answer[1] = y;
        return answer;
    }
}

https://programmers.co.kr/learn/courses/30/lessons/42747

 

코딩테스트 연습 - H-Index

H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 위키백과1에 따르면, H-Index는 다음과 같이 구합니다. 어떤 과학자가 발표

programmers.co.kr

문제 이해부터 설계까지 어려웠음.. (해결은 했으나 나중에 한번 더 풀어봐야할듯)

 

해결 방안

1. 위의 제시된 문제를 보고 일단 인용횟수를 담은 배열인 citations를 오름차순 정렬해야겠다고 생각했음
 => 정렬을 해놓으면 인용된 논문이 h편 이상인 경우를 찾으면 나머지 논문이 h번 이하 인용되어있는지 확인 안해도 되므로

2. 그리고 정렬된 citations배열을 돌면서 i일 때 가질 수 있는 가장 큰 논문 편수를 h로 정함
 => (h = citations.length-i) h편 이상이므로 해당 i번째 논문을 포함 할 수 있기 때문에

3. 해당 i번째 citations[i]가 h 이상인지 확인 후, answer = h; break;
=> 뒤로 갈수록 i가 커져 논문 편수(h)가 줄어듬으로 break; (처음 조건을 만족하는 h가 가장 최댓값)

 

코드

import java.util.*;

// H-Index
// 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 
// 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 H-Index
// citations: 어떤 과학자가 발표한 논문의 인용횟수를 담은 배열
class Solution {
    public int solution(int[] citations) {
        int answer = 0;
        
        // 0 1 3 5 6
        Arrays.sort(citations);
        
        // n편 중 h번 이상 인용된 논문이 h편 이상 일때 h의 최댓값이 h-index
        int h;
        for(int i=0; i<citations.length; i++){
            
            // i일때 가장 큰 h값(논문 편수)
            h = citations.length-i;
            
            // 논문 인용횟수가 h 이상인지 확인
            if(citations[i] >= h){
                answer = h;
                break;
            }
        }
        
        return answer;
    }
}

https://programmers.co.kr/learn/courses/30/lessons/42840

 

코딩테스트 연습 - 모의고사

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다. 1번 수포자가 찍는 ��

programmers.co.kr

첫 번째 풀이

수포자 3명이 일정하게 문제의 답을 찍으므로 person1, person2, person3 배열로 찍는 답의 순서를 적어줌
그리고 cnt 배열에 수포자 세명의 맞은 문제 갯수를 각각 저장해줌

그 중 가장 많이 맞은 문제 갯수를 찾아 max 변수에 저장해줌
그 후 가장 많이 맞은 문제 갯수와 수포자들의 맞은 문제 갯수를 비교하여 같은 경우 ArrayList에 사람 index 값을 넣어줌

코드

import java.util.*;

// 모의고사
// answers: 정답이 순서대로 들은 answers
class Solution {
    public int[] solution(int[] answers) {
        
        int[] person1 = {1, 2, 3, 4, 5};
        int[] person2 = {2, 1, 2, 3, 2, 4, 2, 5};
        int[] person3 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
        
        int[] cnt = new int[3];
        
        for(int i=0; i<answers.length; i++){
            if(answers[i] == person1[i%5]) cnt[0]++;
            if(answers[i] == person2[i%8]) cnt[1]++;
            if(answers[i] == person3[i%10]) cnt[2]++;
        }
        
        // 가장 높은 점수 
        int max = Math.max(cnt[0], Math.max(cnt[1], cnt[2]));
        
        List<Integer> list = new ArrayList<>();
        
        // 가장 높은 점수를 받은 사람을 찾는 것
        if(max == cnt[0])
            list.add(1);
        if(max == cnt[1])
            list.add(2);
        if(max == cnt[2])
            list.add(3);
        
        int[] answer = new int[list.size()];
        for(int i=0; i<list.size(); i++){
            answer[i] = list.get(i);
        }
       
        return answer;
    }
}

 

두 번째 풀이

코드

import java.util.*;
// 모의고사
class Solution {
    public int[] solution(int[] answers) {
        
        // 찍는 방식
        int[] person1 = {1, 2, 3, 4, 5};
        int[] person2 = {2, 1, 2, 3, 2, 4, 2, 5};
        int[] person3 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
        
        int sum1 = 0;
        int sum2 = 0;
        int sum3 = 0;
        
        // 맞힌 문제 수
        for(int i=0; i<answers.length; i++){
            if(person1[(i%5)] == answers[i])
                sum1++;
            if(person2[(i%8)] == answers[i])
                sum2++;
            if(person3[(i%10)] == answers[i])
                sum3++;
        }
        
        int max = Math.max(sum1, Math.max(sum2, sum3));
        
        List<Integer> list = new ArrayList<>();
        if(max == sum1)
            list.add(1);
        if(max == sum2)
            list.add(2);
        if(max == sum3)
            list.add(3);
        
        if(list.size()>1)
            Collections.sort(list);
        
        int[] answer = new int[list.size()];
        for(int i=0; i<list.size(); i++){
            answer[i] = list.get(i);
        }
        
        return answer;
    }
}

https://programmers.co.kr/learn/courses/30/lessons/42748

 

코딩테스트 연습 - K번째수

[1, 5, 2, 6, 3, 7, 4] [[2, 5, 3], [4, 4, 1], [1, 7, 3]] [5, 6, 3]

programmers.co.kr

 

첫 번째 풀이

문제 설명에 나온 순서대로 구현하면 되는 문제임

코드

import java.util.*;
// k번째 수

class Solution {
    public int[] solution(int[] array, int[][] commands) {
        
        int[] answer = new int[commands.length];
        int[] temp;
        
        // array 있고
        // commands에 [i, j, k] 여러개
        int i, j, k;
        for(int x=0; x<commands.length; x++){
            // i, j, k
            i = commands[x][0];
            j = commands[x][1];
            k = commands[x][2];
            
            // 자른 배열을 temp에 저장
            temp = new int[(j-i) + 1];
            
            // 1. array 배열의 i번째 숫자부터 j번째 숫자까지 잘라서 temp 배열에 저장
            int z = i;
            for(int y=0; y<temp.length; y++){
                temp[y] = array[z-1];
                z++;
            }
            
            // 2. 1에서 나온 배열을 정렬
            Arrays.sort(temp);
            
            // 3. k번째 수를 정답에 저장
            answer[x] = temp[k-1];
        }

		return answer;
    }
}

 

두 번째 풀이

첫 번째 풀이와 거의 비슷하게 구현함 (문제의 절차에 따른 구현)

코드

import java.util.*;
// k번째수
class Solution {
    public int[] solution(int[] array, int[][] commands) {
        int[] answer = new int[commands.length];
        int[] temp;
        
        int i, j, k;
        int index;
        for(int x=0; x<commands.length; x++){
            // i j k
            i = commands[x][0];
            j = commands[x][1];
            k = commands[x][2];
            
            temp = new int[j-i+1];
            index = 0;
            // 1. array 잘라서 temp 배열에 저장
            for(int y=i-1; y<j; y++){
                
                temp[index++] = array[y];
            }
            
            // 2. temp 배열 정렬
            Arrays.sort(temp);
            
            // 3. temp 배열의 k번 째 숫자 answer 배열에 저장
            answer[x] = temp[k-1];
        }
        
        return answer;
    }
}

https://programmers.co.kr/learn/courses/30/lessons/12943

 

코딩테스트 연습 - 콜라츠 추측

1937년 Collatz란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업은 다음과 같습니다. 1-1. 입력된 수가 짝수라면 2��

programmers.co.kr

주어진 num값이 int 형이므로 범위가 초과할수 있어 long으로 변환 후 
알고리즘 구현함

import java.util.*;

// 콜라츠 추측

class Solution {
    public int solution(int num) {
        int answer = 0;
        
        long n = num;
        while(n != 1){
            
            // 홀수
            if(n%2 == 0){
                n = n/2; 
            }
            // 짝수
            else{
                n = (n*3) + 1;
            }
            answer++;
            
            if(answer > 500){
                answer = -1;
                break;
            }
        }
        
        return answer;
    }
}

https://programmers.co.kr/learn/courses/30/lessons/12931

 

코딩테스트 연습 - 자릿수 더하기

자연수 N이 주어지면, N의 각 자릿수의 합을 구해서 return 하는 solution 함수를 만들어 주세요. 예를들어 N = 123이면 1 + 2 + 3 = 6을 return 하면 됩니다. 제한사항 N의 범위 : 100,000,000 이하의 자연수 입출

programmers.co.kr

여러 자료형 변환으로 문제를 해결하였음

import java.util.*;
// 자릿수 더하기

public class Solution {
    public int solution(int n) {
        int answer = 0;

        String stringN = Integer.toString(n);
        String temp;
        // 자릿수 숫자로 변환하여 더하기
        for(int i=0; i<stringN.length(); i++){
            temp = Character.toString(stringN.charAt(i));
            answer += Integer.parseInt(temp);
        }
        
        return answer;
    }
}

https://programmers.co.kr/learn/courses/30/lessons/42628

 

코딩테스트 연습 - 이중우선순위큐

 

programmers.co.kr

min, max 우선순위 큐 두개를 이용하여 구현함

두 자료구조에 든 자료를 일치시키기 위해
minPQ에서 삭제한 값을 maxPQ에서도 삭제하고
maxPQ에서 삭제한 값을 minPQ에서 삭제하였음

** 우선순위 큐에서도 List의 remove() 함수를 사용하여 삭제가 가능하였으며 remove("값")을 넣으면 해당 값을 삭제해줌
(PriorityQueue는 Queue 인터페이스를 사용하고 Queue는 List 인터페이스를 사용하므로 List의 remove함수 사용이 가능함)

import java.util.*;
// 이중우선순위큐

class Solution {
    public int[] solution(String[] operations) {
        int[] answer = {0, 0};
        
        Queue<Integer> minPQ = new PriorityQueue<>();
        Queue<Integer> maxPQ = new PriorityQueue<>(Collections.reverseOrder());
        
        String[] operationItem;
        for(int i=0; i<operations.length; i++){
            
            //삽입일 경우
            if(operations[i].charAt(0) == 'I'){
                operationItem = operations[i].split(" ");
                
                minPQ.offer(Integer.parseInt(operationItem[1]));
                maxPQ.offer(Integer.parseInt(operationItem[1]));
            }
            //삭제일 경우
            else{
                // 빈 큐 일때 해당 연산 무시
                if(minPQ.isEmpty())
                    continue;
                
                operationItem = operations[i].split(" ");
                // 최댓값 삭제
                if(Integer.parseInt(operationItem[1]) == 1){
                    minPQ.remove(maxPQ.poll());
                }
                // 최솟값 삭제
                else{
                    maxPQ.remove(minPQ.poll());
                }
            }
        }
        
        if(!minPQ.isEmpty()){
            answer[0] = maxPQ.peek();
            answer[1] = minPQ.peek();
        }
        else{
            answer[0] = 0;
            answer[1] = 0;
        }
        
        return answer;
    }
}

+ Recent posts