본문 바로가기
코테

[java] 프로그래머스스쿨 연습문제 Lv.1 문제 모음 2

by 상똥 2023. 4. 24.

1. 개인정보 수집기간

코딩테스트 연습 - 개인정보 수집 유효기간 | 프로그래머스 스쿨 (programmers.co.kr)
풀이
1. HashMap에 약관별 기간(terms의 정보)을 저장한다
1-1. key = 약관, value = 기간
2. 날짜를 비교할 때 연, 월, 일을 따로 비교하기가 복잡하므로, 총 일수로 바꿔준다(1년=365일처럼)
2-1. 연*12*28
2-2. 월*28
2-3. 따라서, today = 연*12*28 + 월*28 +일
3. 반복문을 통해 privacies의 원소를 하나씩 읽어가며 2번에서 today를 총 일수로 바꿔준것과 동일하게 바꾼다.
4. 바꾼 총 일수에서 1을 빼준 값과 today의 총 일수를 비교하여, today의 총 일수가 더 크면 answer에 삽입
회고
- String[] 배열 = 문자열.split("\\문자열을 분할할 기준")
- ArrayList 를 array로 바꾸는 법 : list.stream()mapToInt(변수타입 -> 변수타입).toArray();
- 이런 문제는,,, 배열 쓸 생각을 말자,,,^^^^^^
코드 (접은글)
더보기
import java.util.*;

class Solution {
    static int toInt(String input) {
        return Integer.parseInt(input);
    }

    public int[] solution(String today, String[] terms, String[] privacies) {
        String[] temp = today.split("\\.");
        int todayInt = toInt(temp[0]) * 12 * 28 + toInt(temp[1]) * 28 + toInt(temp[2]);

        HashMap<String, Integer> varidity = new HashMap<>(terms.length);
        for (int i = 0; i < terms.length; i++) {
            String[] temp2 = terms[i].split("\\ ");
            varidity.put(temp2[0], toInt(temp2[1]));
        }

        ArrayList<Integer> answer = new ArrayList<>();
        for (int i = 0; i < privacies.length; i++) {
            int term = varidity.get(privacies[i].substring(11, 12)) * 28;
            int year = toInt(privacies[i].substring(0, 4)) * 12 * 28;
            int month = toInt(privacies[i].substring(5, 7)) * 28;
            int day = toInt(privacies[i].substring(8, 10));
            int date = year + month + day + term - 1;

            if (date < todayInt)
                answer.add(i + 1);
        }

        return answer.stream().mapToInt(i -> i).toArray();
    }
}

 

2. 신고 결과 받기

코딩테스트 연습 - 신고 결과 받기 | 프로그래머스 스쿨 (programmers.co.kr)
풀이
1. history에 신고당한 유저별로 해당 유저를 신고한 유저의 목록을 저장한다.
1-1. Map<String, HashSet<String>> history
1-2. history.put(id_list[i], new HashSet<>())
2. idList에 id_list에 저장된 유저의 아이디와 해당 인덱스를 순서대로 저장한다.
2-1. Map<Strong, Integer> idList
2-2. idList.put(id_list[i], i)
3. 유저별로 신고당한 횟수가 k번보다 크거나 같다면 해당 유저를 신고한 유저의 수신 메일 횟수를 증가시킨다.
회고
- HashSet은 인덱스를 사용해 원소를 객체로 가져올 기능이 없음 iteretor 사용
코드 (접은 글)
더보기
import java.util.*;

class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        int[] answer = new int[id_list.length];
        Map<String, HashSet<String>> history = new HashMap<>();
        Map<String, Integer> idList = new HashMap<>();
 
        for (int i = 0; i < id_list.length; i++) {
            history.put(id_list[i], new HashSet<>());
            idList.put(id_list[i], i);
        }
 
        for (int i = 0; i < report.length; i++) {
            String[] str = report[i].split(" ");
            history.get(str[1]).add(str[0]);
        }
 
        for (int i = 0; i < id_list.length; i++) {
            HashSet<String> send = history.get(id_list[i]);
            if (send.size() >= k) {
                for (String name : send) {
                    answer[idList.get(name)]++;
                }
            }
        }
        return answer;
    }
}

 

3. 대충 만든 자판

코딩테스트 연습 - 대충 만든 자판 | 프로그래머스 스쿨 (programmers.co.kr)
풀이
1. 각 문자별로 가장 적게 터치할 수 있는 횟수를 저장한다.
1-1. Map touch에 key=문자, value=최소 터치 횟수를 저장한다.
1-2. for문으로 keymap의 문자들을 파악하며 같은 문자에 대해 인덱스가 더 적은 경우 value값을 바꾼다.
1-3. 나중에 입력할 수 없는 문자르 구분해야 하므로, ArrayList containCheck에 각 문자를 저장한다.
2. 타겟 문자의 최소 터치 횟수를 계산한다.
2-1. for문으로 문자의 터치 횟수를 cnt에 입력한다.
2-2. 만약 containCheck에 문자가 없다면 cnt=-1로 설정 후 break;
회고
- Map 사용시 key값이나 value값의 포함 여부는 그냥 ArrayList활용하는게 더 쉬운 것 같다.
코드 (접은 글)
더보기
import java.util.*;

class Solution {
    public int[] solution(String[] keymap, String[] targets) {
        int[] answer = new int[targets.length];
        ArrayList<String> containCheck = new ArrayList<>();
        HashMap<String, Integer> touch = new HashMap<>();

        for (int i = 0; i < keymap.length; i++) {
            for (int j = 0; j < keymap[i].length(); j++) {
                String tmp = keymap[i].substring(j, j + 1);
                if (!containCheck.contains(tmp)) {
                    touch.put(tmp, j + 1);
                    containCheck.add(tmp);
                } 
                else 
                    if (touch.get(tmp) > j + 1) 
                        touch.replace(tmp, j + 1);
            }
        }

        for (int i = 0; i < targets.length; i++) {
            int cnt = 0;
            for (int j = 0; j < targets[i].length(); j++) {
                String tmp1 = targets[i].substring(j, j + 1);
                if (!containCheck.contains(tmp1)) {
                    cnt = -1;
                    break;
                }
                cnt += touch.get(tmp1);
            }
            if (cnt == 0)
                answer[i] = -1;
            else
                answer[i] = cnt;
        }
        return answer;
    }
}

 

4. 성격 유형 검사하기

코딩테스트 연습 - 성격 유형 검사하기 | 프로그래머스 스쿨 (programmers.co.kr)
풀이
1. Map score에 각 유형과 초기 점수 0을 저장한다.
1-1. 추가하기 쉽게 String형 배열 character에 유형을 저장한다.
1-2. 배열에 유형을 저장할 때, R, C, J, A, T, F, M, N순으로 저장하면 후에 값을 비교하기 편리함
2. choices의 값에 따라 survey의 두 개 유형 중 어디에 점수를 추가할지 선택한 후 추가한다.
2-1. substring으로 유형을 둘로 나눈 후
2-2. choices>4라면 첫 번째 유형에 4-choices 만큼 추가하고
2-3. choices<4라면 두 번째 유형에 choices-4 만큼 추가한다
2-4. replace를 사용하여 Map에 저장하는 것이므로 추가할 값에 꼭 +score.get(유형) 해줘야 함
3. 두 개의 유형을 서로 비교하여 answer에 추가한다.
3-1. 위에 문자를 오름차순으로 배열에 저장했으므로, 반복문을 사용해 score에서 character[i]와 character[i+4]를 비교
회고
- 처음에는 Map 자체를 정렬하려고 했는데 차라리 베열을 사용하는 방식이 쉬움;;
코드 (접은 글)
더보기

 

import java.util.*;

class Solution {
    public String solution(String[] survey, int[] choices) {
        String[] character = {"R", "C", "J", "A", "T", "F", "M", "N"};
        Map<String, Integer> score = new HashMap<>();

        for (String s : character)
            score.put(s, 0);

        for (int i = 0; i < choices.length; i++) {
            String tmp1 = survey[i].substring(0, 1);
            String tmp2 = survey[i].substring(1, 2);
            if (choices[i] < 4)
                score.replace(tmp1, score.get(tmp1) + 4 - choices[i]);
            else if (choices[i] > 4)
                score.replace(tmp2, score.get(tmp2) + choices[i] - 4);
        }

        String answer = "";
        for (int i = 0; i < 4; i++) {
            if (score.get(character[i]) >= score.get(character[i + 4]))
                answer += character[i];
            else
                answer += character[i + 4];
        }
        return answer;
    }
}

 

5. 햄버거 만들기

코딩테스트 연습 - 햄버거 만들기 | 프로그래머스 스쿨 (programmers.co.kr)
풀이
1. 후입후출의 성격을 이용하기 위해 Stack array를 선언한다.
2. ingredient의 값을 array에 저장하고, array의 크기가 4 이상이 되면 맨 뒤부터 1, 2, 3, 1이 순서대로 들어있는지 확인한다.
3. 만약 순서대로 들어있다면 4개의 값을 pop하고 answer의 크기를 늘려준다
회고
- 처음엔 아예 배열 자체를 String으로 바꿔서 풀었는데 시간초과
- String으로 replace를 하든 substring concat을 하든 위보단 시간이 오래 걸리는듯
코드 (접은 글)
더보기
import java.util.*;

class Solution {
    public int solution(int[] ingredient) {
        int answer = 0;
        Stack<Integer> array = new Stack<>();
        for (int i : ingredient) {
            array.push(i);
            if (array.size() > 3) {
                if (array.get(array.size() - 4) == 1 && array.get(array.size() - 3) == 2 && array.get(array.size() - 2) == 3 && array.get(array.size() - 1) == 1) {
                    for (int j = 0; j < 4; j++)
                        array.pop();
                    answer++;
                }
            }
        }


        return answer;
    }
}

'코테' 카테고리의 다른 글

[java] 짝지어 제거하기  (0) 2024.01.11
[java] 귤 고르기  (1) 2024.01.11
[python] 프로그래머스스쿨 더 맵게  (0) 2023.12.14
[Java] 심화 1단계  (1) 2023.11.13
[java] 프로그래머스스쿨 연습문제 Lv.1 문제 모음 1  (0) 2023.04.13