ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프로그래머스 - 체육복 [자바]
    Algorithms/- 프로그래머스 2022. 1. 30. 22:44
     

    코딩테스트 연습 - 체육복

    점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번

    programmers.co.kr

     

    정답

    import java.util.*;
    import java.util.stream.*;
    
    class Solution {
        public int solution(int n, int[] lost, int[] reserve) {
    
            /*
            체격순 번호의 앞 뒤만 가능
            e.g. 5<-4->3
            하나 차이만 가능
    
            최대한 많은 학생
    
            전체 학생 수 : n
            도난당한 학생 번호 : lost
            여벌 학생 번호 : reserve
    
    
            */
    
            int finalLost = lost.length;
    
            Arrays.sort(lost);
            Arrays.sort(reserve);
    
            //데이터 전처리를 해야한다.
            //lost와 reserve에 동일한 숫자가 있으면 제거
             for(int i=0; i<lost.length; i++){
                for(int j=0; j<reserve.length; j++){
                    if(lost[i] == reserve[j] && reserve[j] != -1){
                        lost[i] = -1;
                        reserve[j] = -1;
                        finalLost--;
                        break;
                    }
                }
            }
    
    
    
            //도난 학생들 for 앞뒤자신 번호 비교해서 빌려 받을 수 있으면 lost.length에서 뺀다
            //return은 n - final lost로
            int front = 0;
            int back = 0;
    
            for(int lostNumber : lost){
                for(int i=0; i<reserve.length; i++){
                    if(lostNumber != -1 && reserve[i] != -1 && finalLost >= 0){
                        front = lostNumber - 1;
                        back = lostNumber + 1;
    
                        if(reserve[i] == front
                            || reserve[i] == back){
                            reserve[i] = -1;
                            finalLost--;
                            break;
                        }
                    }
    
                }
            }
            //경우의 수가 1개 더 있음
            //서로 겹치게 받을 수 있는 경우 한명이 다른 선택지가 있다면 그걸 선택하면 모두 참여 가능
    
    
            return n - finalLost;
        }
    }

     

    분석

    • 몇몇 테스트가 통과되지 않았는데 배열이 sort 되지 않은 것이 문제였음

    • 순간 순간 최선의 선택을 하는걸 그리디 알고리즘이라고 한다.

    • 이 문제에서는 전처리로 같은 숫자를 제거하는 것부터 하고 정렬 후 앞뒤 비교를 해야 정답에 도달할 수 있다.

     

    최적 정답

    • O(N)으로 해결함. 분석
    class Solution {
        public int solution(int n, int[] lost, int[] reserve) {
            int[] people = new int[n];
            int answer = n;
    
            for (int l : lost) 
                people[l-1]--;
            for (int r : reserve) 
                people[r-1]++;
    
            for (int i = 0; i < people.length; i++) {
                if(people[i] == -1) {
                    if(i-1>=0 && people[i-1] == 1) {
                        people[i]++;
                        people[i-1]--;
                    }else if(i+1< people.length && people[i+1] == 1) {
                        people[i]++;
                        people[i+1]--;
                    }else 
                        answer--;
                }
            }
            return answer;
        }
    }
    반응형

    댓글

Designed by Tistory.