728x90

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/42888

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이 - 나의 생각

User ID 와 닉네임이 있는데

 

유저가 닉네임을 변경하면

 

지금까지 나왔던 기록에서

 

해당 유저의 닉네임이 다 변경해야 됩니다.

 

그러기 위해서는 2가지만 하면 됩니다.

 

1. 유저의 닉네임 기록

2. 유저의 최종 닉네임으로 기록 남기기

 

1. 유저의 닉네임 기록

 

 HashMap을 사용해서

 

유저별 최종 닉네임을 기록합니다.

 

2. 유저의 최종 닉네임으로 기록 남기기

 

User ID로 닉네임을 불러와 기록합니다.

 

 

코드

 

import java.util.*;

class Solution {
    public String[] solution(String[] record) {
        Map<String, String> nickname = new HashMap<>();
        StringBuilder sb = new StringBuilder();
        
        for(String r : record){
            String[] op = r.split(" ");
            if("Leave".equals(op[0])) continue;
            
            nickname.put(op[1], op[2]);
        }
        
        for(String r : record){
            String[] op = r.split(" ");
            switch (op[0]) {
                case "Enter":
                    sb.append(nickname.get(op[1]) + "님이 들어왔습니다.\n");
                    break;
                case "Leave":
                    sb.append(nickname.get(op[1]) + "님이 나갔습니다.\n");
                    break;
            }
        }
        return sb.toString().split("\n");
    }
}

 

 

 

 

 

 

 

다음에 또 봐요

 

728x90

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/49993

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이 - 나의 생각

스킬트리에

 

유저의 스킬(skill_tree.charAt[i]) 있어?

 

Yes

 

-> 순서 맞아?

 

Yes

skill.charAt[index] == skill_tree.charAt[i]

 

No

flag = false;

 

이런식으로 진행하면 됩니다.

 

 

코드

 

class Solution {
    public int solution(String skill, String[] skill_trees) {
        int answer = 0, index = 0;
        boolean flag = true;
        for(String skill_tree : skill_trees){
            flag = true;
            index = 0;
            for(String sk : skill_tree.split("")){
                if(skill.contains(sk)){
                    if(skill.charAt(index++) != sk.charAt(0)){
                        flag = false;
                        break;
                    }
                }
            }
            
            if(flag) answer++; 
        }
        return answer;
    }
}

 

 

 

 

 

 

 

다음에 또 봐요

 

728x90

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/49994

풀이 - 나의 생각

 

1 -> 2 로 넘어갈 경우

 

방문 길이는 체크 되지만

 

2-> 1 방향으로 가는 경우는

 

체크 되지 않아야 한다.

 

기존에 하던 것처럼 2차원 배열로 방문처리 할 경우

 

위의 경우는 가능하지만

 

3 ->2나, 4->2, 5->2 같은 경우

 

방문 길이가 늘어나야 하지만

 

2가 이미 방문처리 되어 늘어나지 않는다.

 

그걸 어떻게 코딩할까 고민을 하다가

 

방문처리를 3차원으로 하면 되겠다고 생각했다.

 

[방향][맵][맵] 이런 식으로해서

 

들어온 방향 + 반대 방향을 방문 처리 해주면

 

그 외에 방향에서 들어오는 건 방문 길이가 추가 되게 할 수 있다!!

 

 

코드

 

import java.util.*;

class Solution {
    public int solution(String dirs) {
        int answer = 0;
        boolean[][][] visited = new boolean[4][11][11];
        int x = 5, y = 5;
        
        for(int i = 0; i < dirs.length(); i++){
            switch(dirs.charAt(i)){
                case 'U':
                        if(x-1 < 0) continue;
                        x--;
                        if(!visited[0][x][y]){
                            answer++;
                            visited[0][x][y] = true;
                            visited[1][x+1][y] = true;
                        }
                        break;
                case 'D':
                        if(x+1 >= 11) continue;
                        x++;
                        if(!visited[1][x][y]){
                            answer++;
                            visited[1][x][y] = true;
                            visited[0][x-1][y] = true;
                        }
                        break;
                case 'L':
                        if(y-1 < 0) continue;
                        y--;
                        if(!visited[2][x][y]){
                            answer++;
                            visited[2][x][y] = true;
                            visited[3][x][y+1] = true;
                        }
                        break;
                case 'R':
                        if(y+1 >= 11) continue;
                        y++;
                        if(!visited[3][x][y]){
                            answer++;
                            visited[3][x][y] = true;
                            visited[2][x][y-1] = true;
                        }
                        break;
            }
        }
        return answer;
    }
}

 

 

 

 

 

 

 

다음에 또 봐요

 

728x90

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/17684

풀이 - 나의 생각

1. List에 알바벳 A ~ Z를 넣는다.


2. LZW 압축 진행


 2-1. 주어진 문자열을 한글자씩 가져온다.
(현재 문자열이 W, 다음 문자열 C)

 

2-2. W+C가 List에 있는지 확인
Y -> W = W+C, C는 원래 C의 다음 문자열, 2-2로
N -> List에 W를 넣고 List에서 W의 위치를 answer에 저장, 2-1로

 

 

1은 그냥 for문으로 알파벳을 넣어줬다.

 

다른 좋은 방법 아시는 분은 댓글 부탁드립니다.

 

W, C는 W+C가 List에 있으면 계속해서 쌓여간다.

 

예를 들어 W+C가 계속해서 List에 없었던 문자라고 가정을 하겠다.

 

No. W C List.contains(W+C)
1 K A true
2 A K true
3 K A true
4 KA O false
5 O   true

 

4번을 보면 그 전에 W+C(KA)가 이미 List에 들어있던 문자이기에

 

W = W+C, C = (이전)C+1 이 된 걸 볼 수 있다.

 

이건 msg.substring(2, 4)와 같다.

 

그래서 start, end라는 int형 변수를 두어서

 

W = msg.substring(start, end);

C = msg.substring(end, end<msg.length()?end+1:end);

 

이렇게 지정을 해주었다.

 

end<msg.length()?end+1:end 를 해주는 이유는

 

StringIndexOutOfBoundsException를 방지해주기 위해서,

 

쉽게 말해 msg의 범위를 넘어가지 않기 위해서이다.

 

 

이후에는 W+C가 List에 들어있을때까지

 

W를 키워간다.(end++)

 

그러다가 List에 W+C가 들어있을면

 

그 위치를 저장하고

 

start를 end 위치로 바꿔주고 다시 반복하면 된다.

 

아 그리고 팁으로

 

List를 배열로 바꾸는 방법!!!

 

int[] answer;

answer = list.stream().mapToInt(Integer::intValue).toArray();

 

실제로 쓰려다 까먹는 경우가 많긴한데

 

기억하면 좋다.

 

코드

 

import java.util.*;
/*
1. List에 알바벳 A ~ Z를 넣는다.
2. LZW 압축 진행
    2-1. 주어진 문자열을 한글자씩 가져온다.
         현재 문자열이 W, 다음 문자열 C
    2-2. W+C가 List에 있는지 확인
        Y -> W = W+C, C는 원래 C의 다음 문자열, 2-2로
        N -> List에 W를 넣고 List에서 W의 위치를 answer에 저장, 2-1로
*/
class Solution {
    public int[] solution(String msg) {
        int[] answer;
        List<String> LZW = new ArrayList<>();
        List<Integer> index = new ArrayList<>();
        for(char c = 'A'; c <= 'Z'; c++){
            LZW.add(String.valueOf(c));
        }
        
        String[] words = msg.split("");
        String W ="", C;
        int start = 0, end = 1;
        while(end <= msg.length()){
            W = msg.substring(start, end);
            C = msg.substring(end, end<msg.length()?end+1:end);
            
            if(!LZW.contains(W+C)){
                index.add(LZW.indexOf(W)+1);
                LZW.add(W+C);
                start = end;
            }
            end++;
        }
        
        if(LZW.contains(W)){
            index.add(LZW.indexOf(W)+1);
        }else{
            index.add(LZW.size());
        }
        
        answer = index.stream().mapToInt(Integer::intValue).toArray();
        return answer;
    }
}

 

 

 

 

 

 

 

다음에 또 봐요

 

728x90

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/92335

풀이 - 나의 생각

 

1. 주어진 int n을 K진수로 바꾸기

2. 조건에 맞춰 숫자 자르기

3. 그 숫자가 소수인지 확인하기

 

1은

 

Integer.toString(int n, int k)

-> n을 k진수로 변환하여 String 형으로 반환한다.

 

2는

 

String.split("0+")

-> 0 또는 연속된 0을 기준으로 문자열을 분환해줌

 

3은

 

에라토스테네스의 체를 활용했는데

 

원래는 n까지 소수의 개수를 찾는 방식이지만

 

이번에는 n이 소수인지 아닌지 판별하는 방식으로 사용했다.

 

 

코드

 

import java.util.*;

class Solution {
    public int solution(int n, int k) {
        String converted = Integer.toString(n, k);
        String[] nums = converted.split("0+"); // 0 또는 연속된 00을 기준으로 분할
        
        int answer = 0;
        
        for(String s : nums){
            if(isPrimeNumber(s)){
                answer++;
            }
        }
        
        
        return answer;
    }
    
    public static boolean isPrimeNumber(String s){ //에라토스테네스의 체 활용
        long num = Long.parseLong(s);
        if(num <= 1){
            return false;
        }
        
        for(int i = 2; i <= Math.sqrt(num); i++){
            if(num % i == 0){
                return false;
            }
        }
        
        return true;
    }
}

 

 

 

 

 

 

 

다음에 또 봐요

 

728x90

 

 

풀이 - 나의 생각

중요한 점

 

1. 캐시 교체 알고리즘은 LRU(Least Recently Used)를 사용한다.

 

2. Cache Size가 0일 경우가 있다.

 

3. 대 소문자 구분이 없다.

 

처음에 문제를 이해하는데 좀 시간이 걸렸다....

 

1. 캐시 교체 알고리즘은 LRU(Least Recently Used)를 사용한다. 에 대해 생각해봅시다.

 

LRU가 뭐지? 라고 생각했다가

 

단어를 보니 대충

 

아 최근에 사용한 것들을 캐시에 넣어놓는 방법이겠다

 

라고 생각했고

 

주어지는 cache size는

 

저장하는 캐시의 최대 개수겠다고 생각했다.

 

그래서 이 생각을 토대로 주어진

 

test case를 풀어보니 정답이 나와서 그렇게 풀었다.

 

즉. LRU는 최근 사용된 것을 캐시에 저장한다.

 

저장할 수 있는 캐시의 개수는 cache size

 

새로운 것이 들어올때는 가장 처음에 들어온 것을 내보낸다.

 

cache hit 은 새로 들어오려는 게 이미 캐시에 있는 경우

 

cache miss 는 없는 경우이다.

 

2. Cache Size가 0일 경우

 

캐시의 사이즈가

 

주어진 cache size 를 넘어가는 경우(같은 경우로 해도 됨)와

 

넘어가지 않는 경우에 따라

 

처리하는 방식이 다른데

 

cache size를 넘어가는 경우

 

캐시의 맨 앞의 것을 삭제하고

 

새로운 것을 뒤로 넣어야 한다.

 

그런데

 

주어진 cache size가 0일 경우

 

캐시에 들어있는 것도 없는데

 

삭제를 하려고 해서 에러가 난다.

 

그러니까 cache size가 0일 경우를

 

예외처리 해줘야 한다.

 

3. 대소문자 구분이 없다

 

그냥 toUpperCase() or toLowerCase()를 사용하면 끝

 

 

기타

 

이 문제는 2017년 카카오 코테에서

 

3번으로 나와, 정답률 45.26%를 기록한 문제이다.

 

문제의 난이도가 그렇게 높지 않은데도

 

정답률이 낮은 이유는

 

LRU, cache hit, cache miss 와 같은 용어에 익숙하지 않았서

 

문제를 이해하는데 어려움을 겪었기 때문이지 않을까 생각한다.

 

 

 

코드

 

import java.util.*;

class Solution {
    public int solution(int cacheSize, String[] cities) {
        int answer = 0;
        List<String> lru = new ArrayList<>();
        /*
        캐시에 있어?
        Yes -> 캐시 안의 도시 삭제, 맨 끝으로 입력 = cash hit = 1
        No -> cash miss = 5
        List size가 cache size를 넘어가?
        Yes -> 가장 맨 앞의 도시 삭제, 맨 끝에 새로운 도시 입력
        No -> 그냥 추가
        */
        if(cacheSize == 0) return 5*cities.length;
        for(String name : cities){
            String city = name.toUpperCase();
            if(lru.contains(city)){
                answer+=1;
                lru.remove(city);
                lru.add(city);
            }else{
                answer+=5;
                if(lru.size() >= cacheSize){
                    lru.remove(0);
                    lru.add(city);   
                }else{
                    lru.add(city);   
                }
            }
        }
        return answer;
    }
}

 

 

 

 

 

 

 

다음에 또 봐요

 

+ Recent posts