enoch012 / JavaBasicStudy

Java 기초 스터디 (2023.09 ~ 10)
0 stars 1 forks source link

10월 26일 / 코딩테스트 연습 (gwangho) #28

Open SDeung01 opened 1 year ago

SDeung01 commented 1 year ago

문제 1: 핸드폰 번호 가리기

문제

입출력 예

phone_number | return -- | -- "01033334444" | "*******4444" "027778888" | "*****8888"

문제 풀이

image

회고

SDeung01 commented 1 year ago

문제2 : 숫자 짝꿍

문제

입출력 예

X | Y | result -- | -- | -- "100" | "2345" | "-1" "100" | "203045" | "0" "100" | "123450" | "10" "12321" | "42531" | "321" "5525" | "1255" | "552"

문제 풀이

import java.util.HashMap;
import java.util.Map;
import java.lang.Math;

class Solution {
    public String solution(String X, String Y) {
        String answer = "";
        Map<Integer, Integer> mapX = freqMap(X);
        Map<Integer, Integer> mapY = freqMap(Y);

        StringBuilder sb = new StringBuilder("");

        // 큰 수 부터 작은 수로 반복해야 가장 큰 값을 구할 수 있다.
        // "00~0"의 경우 "0"으로 출력되어야 하므로 반복횟수를 1회
        // 그 외는 같은 숫자의 중복도 중 낮은 값으로 반복한다.
        // (예를 들어 2가 각각 2개 3개 있다면 2번만 사용할 수 있다.)
        for(int i = 9; i >= 0; i--){
            if(mapX.containsKey(i) && mapY.containsKey(i)){
                int repeat = (i == 0) && (sb.toString().equals("")) ? 1 : Math.min(mapX.get(i),mapY.get(i));
                sb.append(makeNum(i,repeat));
            }
        } answer = sb.toString();
        // 만약 마지막까지 동일한 숫자가 없다면 "-1" 을 반환한다.
        return answer.equals("") ? "-1" : answer;
    }

    // 0~9 사이에 존재하는 정수 k의 중복도를 value로 가지는 Map을 반환한다.
    private Map<Integer, Integer> freqMap(String strNum){
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < strNum.length(); i++){
            int key = strNum.charAt(i) - '0';
            map.put(key, map.getOrDefault(key, 0) + 1);
        } return map;
    }

    // 숫자를 중복도만큼 반복한 문자열을 반환한다.
    private String makeNum(int i, int repeatCnt){
        String num = Integer.toString(i);
        return num.repeat(repeatCnt);
    }
}

image

회고

class Solution { public String solution(String X, String Y) { int[] arrX = makeArr(X); int[] arrY = makeArr(Y);

    StringBuilder sb = new StringBuilder("");

    for(int i = 9; i >= 0; i--){
        if(arrX[i] > 0 && arrY[i] > 0){
            sb.append(makeNum(i,arrX[i],arrY[i]));
        }
    } 
    String answer = sb.toString();

    return answer.equals("") ? "-1" : 
           answer.charAt(0) == '0' ? "0" : answer;
}

private int[] makeArr(String strNum){
    int[] arr = new int[10];

    for(char ch : strNum.toCharArray()){
        int num = ch - '0';
        arr[num] += 1;
    }
    return arr;
}

private String makeNum(int i, int X, int Y){
    String num = Integer.toString(i);
    return num.repeat(Math.min(X, Y));
}

}


![image](https://github.com/enoch012/JavaBasicStudy/assets/145359737/2f6a8d6d-9d05-4327-8d5e-38dc98935760)
SDeung01 commented 1 year ago

문제 3 : 키패드 누르기

문제

  1. 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
  2. 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
  3. 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
  4. 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다. 4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.
    • 순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.

입출력 예

numbers | hand | result -- | -- | -- [1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] | "right" | "LRLLLRLLRRL" [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] | "left" | "LRLLRRLLLRR" [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] | "right" | "LLRLLRLLRL"

문제풀이

import java.util.*;

class Solution {
    public String solution(int[] numbers, String hand) {
        //indexOf를 사용하기 위해 키패드의 키들을 List 형태로 저장
        // *과 #은 사용하지 않으므로 각각 최대값과 최소값으로 임의지정하여 넣음
        int star = Integer.MAX_VALUE, sharp = Integer.MIN_VALUE;
        List<Integer> keypad = Arrays.asList(1,2,3,4,5,6,7,8,9,star,0,sharp);
        // 이전 손가락의 위치(시작지점 *,#)
        int[] prev_L = {1,4}, prev_R = {3,4};
        StringBuilder sb = new StringBuilder();
        // 규칙에 맞춰 "L" 또는 "R"을 문자열에 더한다
        for(int number : numbers){
            int [] now = location(keypad,number);

            if(number % 3 == 1){
                sb.append("L");
                prev_L = now;
            } else if (number % 3 == 0 && number != 0){
                sb.append("R");
                prev_R = now;
            } else {
                int distance_L = distance(now, prev_L);
                int distance_R = distance(now, prev_R);
                if(distance_L < distance_R) {
                    sb.append("L");
                    prev_L = now;
                } else if (distance_L > distance_R) {
                    sb.append("R");
                    prev_R = now;
                } else {
                    if(hand.equals("left")) {
                        sb.append("L");
                        prev_L = now;
                    } else {
                        sb.append("R");
                        prev_R = now;
                    }
                }
            }
        }
        return sb.toString();
    }
    // 1차원인 keypad의 List를 3으로 나누어 몫과 나머지로 x,y 좌표를 구하여 반환
    private int[] location(List<Integer> keypad, int number){
        int xPoint = (keypad.indexOf(number) % 3) + 1;
        int yPoint = (keypad.indexOf(number) / 3) + 1;
        int[] loc = {xPoint, yPoint};
        return loc;
    }
    // 손가락이 위치한 키에서 눌러야할 키 까지 거리를 측정하여 반환
    private int distance(int[] now, int[] prev){
        return Math.abs(prev[0] - now[0]) + Math.abs(prev[1] - now[1]);
    }

}

회고