import java.util.*;
class Solution {
    public int[] solution(int brown, int yellow) {
        int[] answer = new int[2];

        int x;
        int y;
        for(int i = 1; i<=yellow;++i) {
            if(yellow % i == 0) {
                x = i;
                y = yellow / i;
                if(x == y) {
                    return new int[]{x+2,x+2};
                }
                if((x+y)*2+4 == brown) {
                    if(x < y) {
                        int tmp = y;
                        y = x;
                        x = tmp;
                    }
                    return new int[]{x+2,y+2};
                }
            }
        }
        return answer;
    }
}

yellow와 brown의 개수에 대한 공식을 알면 문제를 어렵지 않게 풀 수 있다.

'문제풀이' 카테고리의 다른 글

프로그래머스(모의고사)  (0) 2021.06.10
프로그래머스(섬 연결하기)  (0) 2021.06.08
프로그래머스(조이스틱)  (0) 2021.06.08
프로그래머스(체육복)  (0) 2021.06.07
프로그래머스(큰 수 만들기)  (0) 2021.06.07
import java.util.*;

class Solution {
    public int[] solution(int[] answers) {
        int[] answer = {};
        int[] first = {1,2,3,4,5};
        int[] second = {1,3,4,5};
        int[] third = {3,1,2,4,5};
        int[] uAnswer = new int[3];
        //1,2,3,4,5,1,2,3,4,5,1,2,3,4,5
        //1는 (answer % 5 == 0) ? 5 : answer % 5;
        //(answer % 2 == 1) ? 2 : (answer / 2) % 4;
        //1,3,4,5,1,3,4,5
        //2,1,2,3,2,4,2,5,2,1,2,3,2,4,2,5
        //33,11,22,44,55
        //
        for(int i = 0; i<answers.length;++i) {
            
            int f = first[i%5];
            int s = (i%2 == 0) ? 2 : second[(i/2)%4];
            int t = third[(i/2)%5];
            if(f == answers[i])
                uAnswer[0]++;
            if(s == answers[i])
                uAnswer[1]++;
            if(t == answers[i])
                uAnswer[2]++;
        }
        int max = -1;
        List<Integer> list = new ArrayList<>();
        for(int i = 0; i<uAnswer.length;++i) {
            if(uAnswer[i] > max)
                max = uAnswer[i];
        }
        for(int i = 0; i<uAnswer.length;++i) {
            if(uAnswer[i] == max)
                list.add(i+1);
        }
        answer = new int[list.size()];
        for(int i = 0; i<list.size();++i)
            answer[i] = list.get(i);
        return answer;
    }
}

찍는 방법의 규칙성만 찾아내면 되는 문제

'문제풀이' 카테고리의 다른 글

프로그래머스(카펫)  (0) 2021.06.10
프로그래머스(섬 연결하기)  (0) 2021.06.08
프로그래머스(조이스틱)  (0) 2021.06.08
프로그래머스(체육복)  (0) 2021.06.07
프로그래머스(큰 수 만들기)  (0) 2021.06.07
import java.util.*;

class Bridge implements Comparable<Bridge>{
    int cost;
    int from;
    int to;
    public Bridge(int cost, int from, int to) {
        this.cost = cost;
        if(from < to) {
            this.from = from;
            this.to = to;
        }
        else {
            this.from = to;
            this.to = from;  
        }
    }
    @Override
    public int compareTo(Bridge b) {
        if(b.cost < cost)
            return 1;
        else if(cost < b.cost)
            return -1;
        else
            return 0;
    }
}
class Solution {
    int[] parent;
    public int solution(int n, int[][] costs) {
        int answer = 0;
        parent = new int[n];
        
        for(int i = 0; i < n;++i)
            parent[i] = i;
        
        List<Bridge> list = new ArrayList<>();
        
        for(int[] cost : costs)
            list.add(new Bridge(cost[2], cost[0], cost[1]));
        
        Collections.sort(list);
        
        for(Bridge bridge : list) {
            if(!isSameParent(bridge.from, bridge.to)) {
                answer += bridge.cost;
                setParent(bridge.from, bridge.to);
            }
        }
        return answer;
    }
    public boolean isSameParent(int i, int j) {
        if(getParent(i) != getParent(j))
            return false;
        return true;
    }
    public int getParent(int i) {
        if(parent[i] != i) {
            return getParent(parent[i]);
        }
        return parent[i];
    }
    public void setParent(int i, int j) {
        if(getParent(i) != i) {
            parent[getParent(j)] = getParent(i);
        } 
        else if(getParent(j) != j) {
            parent[getParent(i)]  = getParent(j);
        }
        else {
            parent[j] = parent[i];
        }
    }
}

크루스칼 알고리즘을 써야 하는 문제이다.

처음 봤을 때는 억... 했지만 크루스칼 알고리즘을 다시 복기하고 나니까 크게 어려운 문제는 아니었다.

크루스칼 알고리즘을 써야하는 문제는 이렇게 생겼구나 하고 기억만 해두면 문제는 없을 것 같다.

까먹지 말아야 할 건 setParent에서 parent[j] = ~~~~가 아니라 parent[getParent(j)] = ~~~~~가 되야 한다는 점.

서로 다른 그룹을 연결하기 위해서는 최상위 부모가 되는 노드끼리 연결을 해주어야 하기 때문.

스터디 공부 하고 관련 문제를 풀어봤는데 재미는 있는데... 이거에 시간 쓸 때가 아닌데 어휴

'문제풀이' 카테고리의 다른 글

프로그래머스(카펫)  (0) 2021.06.10
프로그래머스(모의고사)  (0) 2021.06.10
프로그래머스(조이스틱)  (0) 2021.06.08
프로그래머스(체육복)  (0) 2021.06.07
프로그래머스(큰 수 만들기)  (0) 2021.06.07
class Solution {
    public int solution(String name) {
        int answer = 0;
        int nameLen = name.length();
        boolean[] changed = new boolean[nameLen];
        int tmp = 0;
        int trueCount = 0;
        for(int i = 0; i<nameLen;++i) {
            if(name.charAt(i) != 'A') {
                tmp = name.charAt(i)-'A';
                if(tmp < 13)
                    answer += tmp;
                else 
                    answer += (26-tmp);
                changed[i] = true;
                trueCount++;

            }
        }
        changed[0] = false;
        trueCount--;
        
        int min = nameLen;
        int minIndex = -1;
        //0,1,2,3
        //4-3-cursor = 1
        //4-2-cursor = 2
        //4-1-cursor = 3
        // 
        int cursor = 0;
        int distance = 0;
        while(trueCount > 0) {
            min = nameLen;
            minIndex = -1;
            
            for(int i = 0; i<nameLen;++i) {
                if(changed[i] == true) {
                    distance = (cursor > i) ? cursor-i:i-cursor;
                    if(cursor < i) {
                        distance = (nameLen-distance < distance) ? nameLen-distance : distance;
                    }
                    if(min > distance) {
                        min = distance;
                        minIndex = i;
                    }
                }
            }
            changed[minIndex] = false;
            answer += min;
            trueCount--;
            cursor = minIndex;
            
        }
        
        return answer;
    }
}

아 이게 어떻게 레벨2짜리 문제인건지..;;

예전에 문제를 풀었을 때는 글자를 바꾸고 한 칸 옮기고 글자를 바꾸고 한 칸 옮기는 식으로 했었는데 책을 본 효과인지는 모르겠지만.. 글자가 다른 경우를 미리 다 처리하고 나서 옮기는 것에 대해서만 고려할 수 있도록 코드를 짜보니 확실히 깔끔해졌다.

다만 테스트케이스 11에서 틀렸다고 나오는데 다른 사람들 질문 내용을 봐도 감이 안온다. 그리디 알고리즘이라고 할 때 가장 가까운 값으로 이동을 하는 것 외에 고려할게 없을텐데.. 문제가 약간 이상하다고 생각해서 여기까지 하고 넘긴다.

지금은 마땅히 생각나는 문제점을 못찾고 있으니 다음에 한 번 더 봐야겠다.

'문제풀이' 카테고리의 다른 글

프로그래머스(모의고사)  (0) 2021.06.10
프로그래머스(섬 연결하기)  (0) 2021.06.08
프로그래머스(체육복)  (0) 2021.06.07
프로그래머스(큰 수 만들기)  (0) 2021.06.07
프로그래머스(구명보트)  (0) 2021.06.07
class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int answer = 0;
        int[] clothes = new int[n];
        for(int l : lost) {
            clothes[l-1]--;
        }
        for(int r : reserve) {
            clothes[r-1]++;
        }
        
        for(int i = 0; i<clothes.length;++i) {
            if(clothes[i] >0 && i > 0 && clothes[i-1] == -1) {
                clothes[i-1]++;
                clothes[i]--;
                System.out.println(i+ " "+ (i-1));
            }
            else if(clothes[i] > 0 && i+1 <clothes.length && clothes[i+1] == -1) {
                clothes[i+1]++;
                clothes[i]--;
                System.out.println(i+ " "+ (i+1));
            }
            /*
            if(clothes[i] > 0 && i+1 <clothes.length) {
                clothes[i+1]++;
                clothes[i]--;
            }*/
            
        }
        for(int i : clothes) {
            System.out.print(i);
            if(i >= 0)
                answer++;
        }
        return answer;
    }
}

처음 풀 때 어디서 꼬였었는데 넘겼다가 오늘 다시 풀어봤다.

clothes[]를 초기화하면 기본적으로 다 0이 들어가 있으므로 0을 옷을 1장 보유한 상태로 가정한다.

도둑맞은걸 빼고 여분을 더해준 뒤해 알고리즘이 시작된다.

왼쪽에서 오른쪽으로 진행될 예정이기 때문에 왼쪽을 우선적으로 빌려주고 왼쪽이 옷을 가지고 있을 경우, 오른쪽에 빌려주는 형태로 진행이 된다.

여분을 계속 우측으로 넘기면 좋지 않을까 싶었지만 옷은 없는 사람한테만 직접 빌려줘야 하나보다.

 

'문제풀이' 카테고리의 다른 글

프로그래머스(섬 연결하기)  (0) 2021.06.08
프로그래머스(조이스틱)  (0) 2021.06.08
프로그래머스(큰 수 만들기)  (0) 2021.06.07
프로그래머스(구명보트)  (0) 2021.06.07
프로그래머스(단속카메라)  (0) 2021.06.07
import java.util.*;
class Solution {
    public String solution(String number, int k) {
        String text = "0";
        int len = number.length();
        k = number.length()-k;
        Stack<String> s = new Stack<>();//stack을 어떻게 유추하나
        s.push(number.substring(0,1));
        for(int i = 1; i<len;++i) {
            while(s.size() > 0 &&Integer.parseInt(s.peek()) < Integer.parseInt(number.substring(i,i+1)) && s.size()-1+len-i >= k) {
                s.pop();
            }
            if(s.size() < k)//pop조건에서 제외되어도 사이즈에 따라 예외처리는 해야 한다.
                s.push(number.substring(i,i+1));
        }
        String t = "";
        while(s.size() > 0) {
            t= s.pop()+t;
        }
        while(true) {
            if(t.charAt(0) == '0')
                t = t.substring(1, t.length());
            else
                break;
        }
        return t;
    }
/*
    public String solution(String number, int k) {
        String text = "0";
        int val = -1;
        int max = getRemoveNumT(0,k,number, val);
        
        return Integer.toString(max);
    }
    public int getRemoveNumT(int originI, int k, String number, int max) {
        String tmp = "";
        for(int i = originI; i<number.length()-k+1;++i) {
            if(i == 0)
                tmp = number.substring(i+1, number.length());
            else {
                tmp = number.substring(0, i)+number.substring(i+1, number.length());
            }
            if(k == 1) {
            	if(max < Integer.parseInt(tmp))
            		max = Integer.parseInt(tmp);
            }
            else {
            	int t = getRemoveNumT(i, k-1, tmp, max);
            	if(t > max)
            		max = t;
            }
        }
		return max;
    }
*/
}

처음에 재귀로 했다가 효율성 테스트에서 시간 초과가 떴었다.

뭐가 문제일까 하면서 다른 사람이 질문한 내용을 봤는데 stack을 쓰면 좋다고 하는 글을 보고...

고민해보고 풀어보니까 감탄이 나오더라.

제외해야 되는 글자 수에 걸리지 않는 한에서

peek()보다 현재 값이 크면 값을 pop()하고 push()를 한다.

코딩테스트에서 문제만 푸는건 요새는 다들 하니까 이런 효율성을 찾으려고 해야 한다..

'문제풀이' 카테고리의 다른 글

프로그래머스(조이스틱)  (0) 2021.06.08
프로그래머스(체육복)  (0) 2021.06.07
프로그래머스(구명보트)  (0) 2021.06.07
프로그래머스(단속카메라)  (0) 2021.06.07
카카오 2019 신입 공채 1차 2번 문제  (0) 2018.09.28
import java.util.*;
class Solution {
    public int solution(int[] people, int limit) {
        int answer = 0;
        if(people.length == 1)
            return 1;
        Arrays.sort(people);
        List<Integer> list = new ArrayList<>();
        for(int i = 0; i<people.length;++i)
            list.add(people[i]);
        int len = 0;
        int big = 0;
        while(list.size() > 0) {
            len = list.size();
            big = list.get(len-1);
            if(list.size() >1 && big+list.get(0) <= limit) {
                list.remove(list.size()-1);
                list.remove(0);
            }
            else {
                list.remove(list.size()-1);
            }
            answer++;
        }
        
        return answer;
    }
}

인원을 무게 순으로 정렬한다.

가장 무게가 나가는 사람이 가장 가벼운 사람을 태우지 못하면 배 하나 들고 나간다.

태울 수 있으면 태운다. 끝이다.

지금 생각해보니 저걸 list로 하지말고 deque를 쓰는게 좋았을텐데..

deque나 set이나 회사에서 잘 안쓰는 자료구조는 까먹을 때가 많아서 문제다.

import java.util.*;
class route implements Comparable<route>{
    int a;
    int b;
    int c;
    public route(int a, int b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    @Override
    public int compareTo(route r) {
        if(a < r.a)
            return -1;
        else if(a > r.a)
            return 1;
        else {
            if(c < r.c)
                return -1;
            else if(c > r.c)
                return 1;
            else 
                return 0;
        }
    }
}

class Solution {
    public int solution(int[][] routes) {
        int answer = 0;
        List<route> list = new ArrayList<>();
        for(int i = 0; i<routes.length;++i) {
            list.add(new route(routes[i][0],i, 0));
            list.add(new route(routes[i][1],i, 1));
        }
        
        Collections.sort(list);
        //Queue<route> stack = new LinkedList<>();
        //int min = list.get(0).a;
        //int max = list.get(list.size()-1).a;
        //stack.add(list.get(0));
        int minC = -30001;
        for(int i = 0; i<list.size();++i) {
            route t = list.get(i);
            if(t.c == 1) {
                if(minC < routes[t.b][0]) {
                    answer++;
                    minC = t.a;
                }
            }
        }
        // c             d
        //-20 1 0, -18 3 0, -14 2 0, -13 3 1, -5 4 0, -5 2 1, -3 4 1, 15 1 1
        
        //들어온 뒤에 처음 나가는 것이 있을 경우 카메라를 놓는다.
        //나간 것이 존재하고 이후에 값이 들어올 경우, 
        return answer;
    }
}

 

취업한 이후로 블로그 쓰고 싶지 않았는데.. 계속 했어야 했다.

스터디 책에서 그리디 알고리즘이 나왔으므로 관련 문제를 올려본다.

키 포인트는 카메라를 두는 조건을 명확히 설정을 하고 이에 맞춰 코딩을 해야 한다.

일단 차량이 들어오고 나가는 각 시점을 시간 순으로 정렬을 해야겠다 싶어서 이를 따로 쪼개 list에 넣고 정렬을 했다.

차량 진출시점의 최소값이 -30000이었기 때문에 우선 카메라 위치의 min 값으로 -30001을 잡았고

for문을 돌리면서 list 내의 객체가 out일 때(c==1) 마지막 카메라의 위치가 차가 진입한 시점보다 이전이면 나갈때 카메라를 하나 세워주는 식으로 진행했다. 차량의 inout을 시간순으로 정렬했기 때문에 마지막 카메라 위치만 알면 되니까 값을 따로 기억하지는 않고 마지막 카메라 위치만 체크해서 풀면 꽤 간단했다.

2. 실패율

슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다.

이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.

  • 실패율은 다음과 같이 정의한다.
    • 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수

전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.

제한사항
  • 스테이지의 개수 N은 1 이상 500 이하의 자연수이다.
  • stages의 길이는 1 이상 200,000 이하이다.
  • stages에는 1 이상 N + 1 이하의 자연수가 담겨있다.
    • 각 자연수는 사용자가 현재 도전 중인 스테이지의 번호를 나타낸다.
    • 단, N + 1 은 마지막 스테이지(N 번째 스테이지) 까지 클리어 한 사용자를 나타낸다.
  • 만약 실패율이 같은 스테이지가 있다면 작은 번호의 스테이지가 먼저 오도록 하면 된다.
  • 스테이지에 도달한 유저가 없는 경우 해당 스테이지의 실패율은 0 으로 정의한다.
입출력 예
N stages result
5 [2, 1, 2, 6, 2, 4, 3, 3] [3,4,2,1,5]
4 [4,4,4,4,4] [4,1,2,3]
입출력 예 설명

입출력 예 #1

1번 스테이지에는 총 8명의 사용자가 도전했으며, 이 중 1명의 사용자가 아직 클리어하지 못했다. 따라서 1번 스테이지의 실패율은 다음과 같다.

  • 1번 스테이지 실패율 : 1/8

2번 스테이지에는 총 7명의 사용자가 도전했으며, 이 중 3명의 사용자가 아직 클리어하지 못했다. 따라서 2번 스테이지의 실패율은 다음과 같다.

  • 2번 스테이지 실패율 : 3/7

마찬가지로 나머지 스테이지의 실패율은 다음과 같다.

  • 3번 스테이지 실패율 : 2/4
  • 4번 스테이지 실패율 : 1/2
  • 5번 스테이지 실패율 : 0/1

각 스테이지의 번호를 실패율의 내림차순으로 정렬하면 다음과 같다.

  • [3,4,2,1,5]

입출력 예 #2

모든 사용자가 마지막 스테이지에 있으므로 4번 스테이지의 실패율은 1이며 나머지 스테이지의 실패율은 0이다.

  • [4,1,2,3]

문제 풀이

문제를 읽어보면 알 수 있듯이 이 문제는 정렬을 이용해서 풀 수 있습니다.

먼저 주어진 배열의 길이를 이용하여 전체 사용자 수를 구하고, stages 를 순회하며 각 스테이지에 몇 명의 사용자가 도달했는지 세줍니다. 이렇게 만들어둔 배열(각 스테이지별 사용자 수가 들어있는)을 순회하면서 stages 를 참고하여 스테이지별 실패율을 계산합니다. 이때, 스테이지에 도달한 사용자가 0명인 경우 예외 처리를 해야 합니다. 스테이지별 실패율을 구했다면, 각 스테이지 번호와 묶어서 실패율 내림차순으로 정렬합니다. 실패율이 같은 경우는 스테이지 번호가 작은 것을 먼저 오도록 정렬하면 됩니다.





시험 볼 때 유일하게 풀었던 문제 같은데 어떻게 풀었었는지 기억이 안난다.


다르게 한번 풀어보았다. 워낙에 정렬 문제가 많다보니까 클래스를 별도로 만드는 것에 익숙해지는 중이다.



import java.util.*;

class Stage implements Comparable<Stage>
{
	public float failP;
	public int stageNum;
	public Stage(int n, float temp)
	{
		failP = temp;
		stageNum = n;
	}
	@Override
	public int compareTo(Stage o) {

		if(o.failP > failP)
		{
			return 1;
		}
		else if(o.failP == failP)
		{
			if(o.stageNum > stageNum)
			{
				return -1;
			}
			else
			{
				return 1;
			}
		}
		else
		{
			return -1;
		}
	}
}
public class kakaoEx03 {

	public static void main(String[] args) {

		int[] arr1 = solution(5, new int[]{2,1,2,6,2,4,3,3});
		int[] arr2 = solution(4, new int[] {4,4,4,4,4});
		
		for (int i = 0; i < arr1.length; ++i)
			System.out.print(arr1[i]);
		System.out.println();
		for(int i : arr2)
			System.out.print(i);
	}

	public static int[] solution(int N,int[] stages) {
		int[] answer = null;
		float[] d = new float[N];
		int[] clear = new int[N];
		int[] fail = new int[N];
		Arrays.sort(stages);
		answer = new int[N];
		for(int i = 0; i<stages.length;++i)
		{
			if(N>=stages[i])
			{
				fail[stages[i]-1]++;
				for(int j = 0; j<N&&j<stages[i];++j)
				{
					clear[j]++;
				}
			}
			else
			{
				for(int j = 0; j<N;++j)
				{
					clear[j]++;
				}
			}
		}
		List<Stage> list = new ArrayList<>();
		for(int i = 0; i<N;++i)
		{
			float temp;
			if(clear[i]+fail[i] != 0)
			{
				
				temp = (float)fail[i] / (clear[i]+fail[i]);

			}
			else
			{
				temp = 0;
			}
			list.add(new Stage(i+1,temp));
		}
		Collections.sort(list);
		for(int i = 0; i<N;++i)
		{
			answer[i] = list.get(i).stageNum;
		}
	return answer;
}

}


1. 오픈채팅방

카카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다.

신입사원인 김크루는 카카오톡 오픈 채팅방을 개설한 사람을 위해, 다양한 사람들이 들어오고, 나가는 것을 지켜볼 수 있는 관리자창을 만들기로 했다. 채팅방에 누군가 들어오면 다음 메시지가 출력된다.

“[닉네임]님이 들어왔습니다.”

채팅방에서 누군가 나가면 다음 메시지가 출력된다.

“[닉네임]님이 나갔습니다.”

채팅방에서 닉네임을 변경하는 방법은 다음과 같이 두 가지이다.

  • 채팅방을 나간 후, 새로운 닉네임으로 다시 들어간다.
  • 채팅방에서 닉네임을 변경한다.

닉네임을 변경할 때는 기존에 채팅방에 출력되어 있던 메시지의 닉네임도 전부 변경된다.

예를 들어, 채팅방에 “Muzi”와 “Prodo”라는 닉네임을 사용하는 사람이 순서대로 들어오면 채팅방에는 다음과 같이 메시지가 출력된다.

“Muzi님이 들어왔습니다.” “Prodo님이 들어왔습니다.”

채팅방에 있던 사람이 나가면 채팅방에는 다음과 같이 메시지가 남는다.

“Muzi님이 들어왔습니다.” “Prodo님이 들어왔습니다.” “Muzi님이 나갔습니다.”

Muzi가 나간후 다시 들어올 때, Prodo 라는 닉네임으로 들어올 경우 기존에 채팅방에 남아있던 Muzi도 Prodo로 다음과 같이 변경된다.

“Prodo님이 들어왔습니다.” “Prodo님이 들어왔습니다.” “Prodo님이 나갔습니다.” “Prodo님이 들어왔습니다.”

채팅방은 중복 닉네임을 허용하기 때문에, 현재 채팅방에는 Prodo라는 닉네임을 사용하는 사람이 두 명이 있다. 이제, 채팅방에 두 번째로 들어왔던 Prodo가 Ryan으로 닉네임을 변경하면 채팅방 메시지는 다음과 같이 변경된다.

“Prodo님이 들어왔습니다.” “Ryan님이 들어왔습니다.” “Prodo님이 나갔습니다.” “Prodo님이 들어왔습니다.”

채팅방에 들어오고 나가거나, 닉네임을 변경한 기록이 담긴 문자열 배열 record가 매개변수로 주어질 때, 모든 기록이 처리된 후, 최종적으로 방을 개설한 사람이 보게 되는 메시지를 문자열 배열 형태로 return 하도록 solution 함수를 완성하라.

제한사항
  • record는 다음과 같은 문자열이 담긴 배열이며, 길이는 1 이상 100,000 이하이다.
  • 다음은 record에 담긴 문자열에 대한 설명이다.
    • 모든 유저는 [유저 아이디]로 구분한다.
    • [유저 아이디] 사용자가 [닉네임]으로 채팅방에 입장 - “Enter [유저 아이디] [닉네임]” (ex. “Enter uid1234 Muzi”)
    • [유저 아이디] 사용자가 채팅방에서 퇴장 - “Leave [유저 아이디]” (ex. “Leave uid1234”)
    • [유저 아이디] 사용자가 닉네임을 [닉네임]으로 변경 - “Change [유저 아이디] [닉네임]” (ex. “Change uid1234 Muzi”)
    • 첫 단어는 Enter, Leave, Change 중 하나이다.
    • 각 단어는 공백으로 구분되어 있으며, 알파벳 대문자, 소문자, 숫자로만 이루어져있다.
    • 유저 아이디와 닉네임은 알파벳 대문자, 소문자를 구별한다.
    • 유저 아이디와 닉네임의 길이는 1 이상 10 이하이다.
    • 채팅방에서 나간 유저가 닉네임을 변경하는 등 잘못 된 입력은 주어지지 않는다.
입출력 예
record result
[“Enter uid1234 Muzi”, “Enter uid4567 Prodo”,”Leave uid1234”,”Enter uid1234 Prodo”,”Change uid4567 Ryan”] [“Prodo님이 들어왔습니다.”, “Ryan님이 들어왔습니다.”, “Prodo님이 나갔습니다.”, “Prodo님이 들어왔습니다.”]
입출력 예 설명

입출력 예 #1 문제의 설명과 같다.

문제 풀이

첫 번째 문제답게 큰 고민 없이 연관 배열(맵)을 이용해서 쉽게 풀 수 있습니다.

record 를 순회 하면서

  • Enter, Leave 인 경우 유저 아이디와 함께 정답에 출력될 메시지의 종류를 기록을 해둡니다. 이렇게 기록해둔 것을 events 라고 합시다.
  • Enter, Change 인 경우 연관 배열을 이용하여 각 유저 아이디를 키로, 닉네임을 값으로 저장해 둡니다. 이렇게 해서 최종 닉네임을 유저 아이디별로 유지합니다.

이제 events 를 순회하면서 채팅방에 출력할 메시지를 생성할 때, 연관 배열에 저장된 아이디별 최종 닉네임을 이용하면 됩니다.





후.... 반성해야 한다. HashMap을 제대로 생각도 못해서 후...................... 공부를 제대로 안하고 본 내가 잘못이지..


여기서 크게 쏘였지만 다른 곳은 잘 보기 위해서 열심히 공부를 해야지.





import java.util.*;

public class kakaoEx03 {

	public static void main(String[] args) {

		String[] arr = solution(new String[]{"Enter uid1234 Muzi", "Enter uid4567 Prodo","Leave uid1234","Enter uid1234 Prodo","Change uid4567 Ryan"});
		for (int i = 0; i < arr.length; ++i)
			System.out.println(arr[i]);
	}

	public static String[] solution(String[] record) {
		String[] answer = null;
		HashMap<String, String> idNick = new HashMap<String, String>();
		String[][] splitR = new String[record.length][2];
		int events = 0;
		for(int i = 0; i < splitR.length;++i)
		{
			String[] temp = record[i].split(" ");
			if(temp[0].equals( "Enter" )|| temp[0].equals( "Change" ))
			{
				idNick.put(temp[1], temp[2]);
			}
			if(temp[0].equals( "Enter" )|| temp[0].equals( "Leave" ))
			{
				splitR[events][0] = temp[0];
				splitR[events++][1] = temp[1];
			}
		}
		answer = new String[events];
		int count = 0;
		for(int i = 0; i < events;++i)
		{
			if(splitR[i][0].equals("Enter"))
			{
				answer[count++] = idNick.get(splitR[i][1])+"님이 들어왔습니다.";
			}
			else if(splitR[i][0].equals("Leave"))
			{
				answer[count++] = idNick.get(splitR[i][1])+"님이 나갔습니다.";
			}
		}
		
	return answer;
}

}


+ Recent posts