프로그래머스

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

programmers.co.kr

 


풀이1

이렇게 푸니까 일단 통과는 하지만 테스트케이스 10번에서 시간이 오래 걸렸다.

  • 일단 k개를 제외하고 number.length() - k 개수만큼 숫자를 골라야 한다. => 반복문
  • 그리고 두번째 반복문에서는 각 회차에서 가장 큰 수(max)를 골라줘야 한다. 그런데 이 가장 큰 수를 고를 때 주의해야할 점이 있다. 바로 어디까지 중에서 (몇번째 인덱스까지) 가장 큰 수를 고를 것인가? 이다.
    • 1924, k=2라면 max를 고를 때 192 중에서 골라야한다. 왜냐면 두개의 수를 골라야 하기 때문에 (k=2이므로 2개 숫자 제거) 예를 들어, 1879라고 생각해보면 무작정 9를 고르면 그건 가장 큰 수가 되지 못하기 때문이다. 
    • 그래서 아래 그림과 같이 생각을 하면서 규칙을 찾아 k + i 인덱스까지 중에서 회차마다 가장 큰 수를 골라서 append해준다.

class Solution {
    public String solution(String number, int k) {
        StringBuffer sb = new StringBuffer();
        int index = 0;
        // 우리는 number.length() - k 개수를 숫자를 뽑을것이다
        for (int i = 0; i < number.length() - k; i++) {
            int max = 0;
            //큰수를 만들기 위해 뒤 숫자들 중 가장 큰수를 뽑아서 붙여줘야 한다
            for (int j = i; j <= i+k ; j++) {
                if (number.charAt(j) - '0' > max) {
                    max = number.charAt(i) - '0';
                    index = j + 1; // 다음 숫자부터 골라야하므로
                }
            }
            sb.append(max);
        }

        return sb.toString();
    }
}

반복문을 두번돌아 테스트10에서 속도가 매우 느리다는 것을 알 수 있다.


풀이2

다른분들의 풀이를 보니 스택을 이용해서 푼 풀이도 있었다. 

 

  • 스택에 들어있는 문자(stack.peek()) 가 현재 i번째 문자(charAt(i))보다 작으면 꺼낸다.
  • 문제는 k개의 숫자를 제거하는 것이므로, pop할때 k-- 로 k를 줄여준다. 
  • k개의 숫자가 pop되면(제거되면) 종료 후 스택에 있는 값을 꺼내준다. 

이런식으로 풀면 왼쪽에서부터 (앞에서부터) k개의 작은 수를 차례로 제거할 수 있다.

import java.util.Stack;
class Solution {
    public String solution(String number, int k) {
        char[] result = new char[number.length() - k];
        Stack<Character> stack = new Stack<>();

        for (int i=0; i<number.length(); i++) {
            char c = number.charAt(i);
            while (!stack.isEmpty() && stack.peek() < c && k-- > 0) {
                stack.pop();
            }
            stack.push(c);
        }
        for (int i=0; i<result.length; i++) {
            result[i] = stack.get(i);
        }
        return new String(result);
    }
}

문제

 

코딩테스트 연습 - 2주차

[[100,90,98,88,65],[50,45,99,85,77],[47,88,95,80,67],[61,57,100,80,65],[24,90,94,75,65]] "FBABD" [[70,49,90],[68,50,38],[73,31,100]] "CFD"

programmers.co.kr

 

풀이

Map의 getOrDefault 메소드를 이용하여 같은 점수가 여러개 존재하는지 알아냈고, TreeMap을 이용하여 최고점과 최저점을 알아냈다. TreeMap은 key값이 자동정렬되기 때문에 key를 점수로 설정하면 firstKey()와 lastKey()로 최저점과 최고점을 알아낼 수 있었기 때문이다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.util.*;
 
class Solution {
    public String solution(int[][] scores) {
       StringBuilder answer = new StringBuilder();
 
        for(int i = 0; i<scores[0].length; i++) {
            int total = 0
            int person = scores[0].length;
            TreeMap<Integer, Integer> hm = new TreeMap<>();
 
            for(int j = 0; j<scores[i].length; j++) {
                hm.put(scores[j][i], hm.getOrDefault(scores[j][i], 0+ 1);
                total += scores[j][i];
            }
 
            if(scores[i][i] == hm.firstKey() && hm.get(hm.firstKey()) < 2) {
                total -= hm.firstKey();
                person -= 1;
            }
 
            if(scores[i][i] == hm.lastKey() && hm.get(hm.lastKey()) < 2) {
                total -= hm.lastKey();
                person -= 1;
            }
 
            answer.append(getGrade(total/person));
        }
 
        return answer.toString();
    }
 
    public String getGrade(double avg) {
        if(avg >= 90) {
            return "A";
        }
 
        else if(avg >= 80) {
            return "B";
        }
 
        else if(avg >= 70) {
            return "C";
        }
        else if(avg >= 50) {
            return "D";
        }
        else
            return "F";
    }
}
cs

 

 

 

아래는 좋아요를 가장 많이 받은 다른 사람의 풀이이다.

본인이 자기자신에게 매긴 점수를 제외하고 최고점과 최저점을 구했고, 구한 최저점과 최고점이 본인이 매긴 점수와 일치할 시에 제외하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
    public String solution(int[][] scores) {
        StringBuilder builder = new StringBuilder();
        for(int i=0; i<scores.length; i++) {
            int max = 0;
            int min = 101;
            int sum = 0;
            int divide = scores.length;
            for(int j=0; j<scores.length; j++) {
                int score = scores[j][i];
                if(i != j) {
                    if(score < min) {
                        min = score;
                    }
                    if(score > max) {
                        max = score;
                    }
                }
                sum += score;
            }
            if(scores[i][i] < min || scores[i][i] > max) {
                sum -= scores[i][i];
                divide--;
            }
            double score = (double) sum / divide;
            builder.append(score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : score >= 50 ? "D" : "F" );
        }
        return builder.toString();
    }
}
cs

'알고리즘 > 프로그래머스' 카테고리의 다른 글

[프로그래머스/java] 큰수 만들기  (0) 2023.07.14

+ Recent posts