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;
    }
}

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

 

코딩테스트 연습 - 라면공장

라면 공장에서는 하루에 밀가루를 1톤씩 사용합니다. 원래 밀가루를 공급받던 공장의 고장으로 앞으로 k일 이후에야 밀가루를 공급받을 수 있기 때문에 해외 공장에서 밀가루를 수입해야 합니��

programmers.co.kr

우선순위 큐를 이용하여 구현함

공급 물량을 내림차순으로 하여 저장하게 하였음
또한 재고가 부족한 경우에 poll() 해서 더해주도록 함
왜냐하면 결국엔 stock이 다 쓴경우에 채워서 쓰면 최소로 공급 받는 방법이 되기 때문임
추가로 우선순위 큐로 구현하였기 때문에 중간에 필요없이 공급받아야 하는 경우 또한 제외할 수 있음

import java.util.*;

// 라면공장
// k-1일 까지의 밀가루 수량 확보 필요

class Solution {
    
    public int solution(int stock, int[] dates, int[] supplies, int k) {
        int answer = 0;
        
        // 내림 차순
        Queue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
        
        int supplyIdx = 0;
        // k-1일까지
        for(int i = 0 ; i < k ; i++){
            // 현재 날짜와 공급 가능일이 같으면 큐에 추가
            if(supplyIdx < dates.length && i == dates[supplyIdx]){
                pq.offer(supplies[supplyIdx]);
                supplyIdx++;
            }
            
            stock--;
            
            // stock 이 -1이 되면 큐에서 빼서 stock 추가
            if(stock == -1) {
                stock += pq.poll();
                answer++;
            }
        }
        
        return answer;
    }
}

+ Recent posts