enoch012 / JavaBasicStudy

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

10월 15일 / 코딩테스트 연습 (gwangho) #17

Open SDeung01 opened 1 year ago

SDeung01 commented 1 year ago

문제 1 : 추억 점수

문제

입출력 예

name | yearning | photo | result -- | -- | -- | -- ["may", "kein", "kain", "radi"] | [5, 10, 1, 3] | [["may", "kein", "kain", "radi"],["may", "kein", "brin", "deny"], ["kon", "kain", "may", "coni"]] | [19, 15, 6] ["kali", "mari", "don"] | [11, 1, 55] | [["kali", "mari", "don"], ["pony", "tom", "teddy"], ["con", "mona", "don"]] | [67, 0, 55] ["may", "kein", "kain", "radi"] | [5, 10, 1, 3] | [["may"],["kein", "deny", "may"], ["kon", "coni"]] | [5, 15, 0]

문제풀이

class Solution { public int[] solution(String[] name, int[] yearning, String[][] photo) { int[] memory = new int[photo.length]; Map<String, Integer> nameMap = new HashMap<>();

    // 인물의 이름을 key로, 대응하는 그리움 점수를 value로 저장
    for(int i = 0; i < name.length; i++){
        nameMap.put(name[i], yearning[i]);
    }

    // 사진에 나오는 인물이 그리운 인물(key)면 그리움 점수(value)를 추억점수에 더하고,
    // 명단에 없는 인물이면 0점(default값)을 더한다.
    for(int j = 0; j < photo.length; j++){
        int memoryPoint = 0;
        for (String key : photo[j]) {
            memoryPoint += nameMap.getOrDefault(key, 0);
        } memory[j] = memoryPoint;
    }

    return memory;
}

}

![image](https://github.com/enoch012/JavaBasicStudy/assets/145359737/7cf9b850-ebab-45c6-9b63-476562f3c1b7)

## 회고
- 그리움점수를 합산하는 코드를 처음에는 if-else로 작성을 하였으나 삼항연산자를 사용하는 편이 좀 더 간결하고 가독성있는 코드로  작성할 수 있을 것 같아 변경하였다.
- 거기서 추가적으로  IDE의 추천에 따라 동일한 결과를 리턴하는 메소드를 사용하여 적용하여 보았다.
- `getOrDefault(Object key, V defaultValue)` 는 Map에 입력한 key가 존재한다면 key에 매핑된 value값을, 존재하지 않는다면 default로 설정된 값을 리턴하는 메소드로 이전에도 List나 배열의 중복요소 검사를 위해 몇번 사용한 적이 있던 메소드다.
- 이미 알고 있던 메소드였음에도 IDE가 추천해주기 전까지는 전혀 떠올리지 못했다. 메소드의 사용처를 한정적으로 생각했기 때문인 것 같다.  메소드를 어디에, 어떻게 응용할 수 있는지 다양한 케이스를 접하는 것도 중요하지만 그 메소드의 정확한 기능과 동작원리를 파악해두는 것 역시 매우 중요할 것 같다.
- (어쨌거나) 아래의 두 코드는 같은 기능을 한다.
```java
  // 입력한 key값이 nameMap에 key로 존재한다면 key에 매핑된 값을 리턴하고, 아닐 경우 0을 리턴한다.
  memoryPoint += nameMap.getOrDefault(key, 0); 

  // 입력한 key값이 nameMap에 key로 존재한다면 key에 매핑된 값을 리턴하고, 아닐 경우 0을 리턴한다.
  memoryPoint += nameMap.containskey(key) ? nameMap.get(key) : 0;
SDeung01 commented 1 year ago

문제 2 : 덧칠하기

문제

입출력 예

n | m | section | result -- | -- | -- | -- 8 | 4 | [2, 3, 6] | 2 5 | 4 | [1, 3] | 1 4 | 1 | [1, 2, 3, 4] | 4

문제풀이

class Solution { public int solution(int n, int m, int[] section) { int count = 0; Set sectionSet = new HashSet<>();

    for(int part : section){
        sectionSet.add(part);
    }

    // 칠할 구역이 남아있으면 롤러를 굴려 m만큼의 구역을 덧칠
    // 덧칠한 구역 내에 페인트를 칠할 다른 구역이 포함되어있다면 그 구역도 sectionSet에서 제외
    for(int part : section){
        if(sectionSet.contains(part)){        
            for(int i = 0; i < m; i++){         
                if(sectionSet.contains(part + i)) { 
                    sectionSet.remove(part + i);
                }
            } count++;
        } if(sectionSet.isEmpty()) break;     // 롤러를 1회 굴린 횟수만큼 카운트가 증가.
    }

    return count;
}

}

![image](https://github.com/enoch012/JavaBasicStudy/assets/145359737/3e54ce11-ec24-445f-bd09-7c902a190790)
![image](https://github.com/enoch012/JavaBasicStudy/assets/145359737/4b624121-d0b7-4318-9522-baa4c2b7dfd8)
![image](https://github.com/enoch012/JavaBasicStudy/assets/145359737/1d3a0533-9ae7-4c37-9587-35573a2fbabf)

## 회고
- 시간제한에 걸릴만큼 느리지는 않았지만 생각만큼 빠르지도 않았고 편차도 제법 큰 편이었다.
- 다음은 다른 사람이 작성한 코드를 참고하여 새로 작성한 코드다.
```java
class Solution {
    public int solution(int n, int m, int[] section) {
        int rollStart = section[0];
        int count = 1;
        for(int i = 1; i < section.length; i++) {
            int rollEnd = rollStart + m - 1;
            if(rollEnd < section[i]) {
                count++;
                rollStart = section[i];
            }
        }
        return count;
    }
}

image

SDeung01 commented 1 year ago

문제 3 : 대충 만든 자판

문제

입출력 예

keymap | targets | result -- | -- | -- ["ABACD", "BCEFD"] | ["ABCD","AABB"] | [9, 4] ["AA"] | ["B"] | [-1] ["AGZ", "BSSS"] | ["ASA","BGZ"] | [4, 6]

문제풀이

import java.util.HashMap;
import java.util.Map;

class Solution {
    public int[] solution(String[] keymap, String[] targets) {
        int[] keyCount = new int[targets.length];
        Map<Character, Integer> keyboard = makeKeyMap(keymap);

        // 입력하려는 문자열 target의 문자를 입력하기 위한 횟수를 count에 합산.
        // 주어진 자판으로 입력할 수 없는 문자가 있다면 -1을 배열에 저장.
        for(int i = 0; i < targets.length; i++){
            int count = 0;
            String target = targets[i];
            for(int j = 0; j < target.length(); j++){
                char targetCh = target.charAt(j);
                if(keyboard.containsKey(targetCh)) { count += keyboard.get(targetCh); }
                else { count = -1; break; }
            }
            keyCount[i] = count;
        }

        return keyCount;
    }

    // keymap의 여러 자판 중 특정 알파벳을 가장 빠르게 입력할 수 있는 값을 저장한 HashMap을 만든다.
    // Map(알파벳, 가장 빠르게 입력할 수 있는 횟수)
    private HashMap<Character, Integer> makeKeyMap(String[] keymap) {
        HashMap<Character, Integer> keyboard = new HashMap<>();

        for (String keyStr : keymap){
            for (int i = 0; i < keyStr.length(); i++){
                char key = keyStr.charAt(i);
                if(!keyboard.containsKey(key)){
                    keyboard.put(key, i + 1);
                } else {
                    if(keyboard.get(key) > i + 1) {
                        keyboard.put(key, i + 1);
                    }
                }
            }
        } return keyboard;
    }

}

image

회고

class Solution { public int[] solution(String[] keymap, String[] targets) { int[] minTouch = new int['Z' - 'A' + 1]; Arrays.fill(minTouch, 200); for (String key : keymap) { for (int i = 0; i < key.length(); i++) { minTouch[key.charAt(i) - 'A'] = Math.min(minTouch[key.charAt(i) - 'A'], i + 1); } } int[] answer = new int[targets.length]; for (int i = 0; i < targets.length; i++) { String target = targets[i]; int sum = 0; boolean canMake = true; for (int j = 0; j < target.length(); j++) { if (minTouch[target.charAt(j) - 'A'] == 200) { canMake = false; break; } sum += minTouch[target.charAt(j) - 'A']; } answer[i] = canMake ? sum : -1; } return answer; } }


- 아스키코드와 char 타입의 연산 특징을 이용하여 문자를 그대로 인덱스로 사용하였다.
- 배열은 배열 내의 원소를 검색하는 메소드(contains)가 존재하지 않고, 한번 정해진 길이 내에서만 추가가 가능하기 때문에 A to Z에 해당하는 길이 배열을 미리 생성하고, 200으로 초기화(`Arrays.fill(int[] a, int val)`) 하였다.(배열의 원소가 200일 경우, 해당 문자는 자판으로 입력 불가능한 문자라는 의미)
- 이후의 구조는 거의 동일하다.
![image](https://github.com/enoch012/JavaBasicStudy/assets/145359737/0a032124-b6cc-4e2b-b2cb-5ead7951c50b)
SDeung01 commented 1 year ago

[Java] 객체와 객체지향 프로그래밍(OOP) 에 대하여 정리해보았습니다. 개념에 대한 이해도에 따라 추후 내용이 수정되거나 추가 될 수 있습니다.