프로그래머스 레벨2 문제 - peulogeulaemeoseu lebel2 munje

개발자 ISA의 공방

일상

프로그래머스 2레벨 끝!

ISA(류) 2021. 11. 15. 14:54

프로그래머스 레벨2 문제 - peulogeulaemeoseu lebel2 munje
2레벨 마무리 직후

코딩테스트를 위해서 프로그래머스 1레벨부터 3레벨까지 모든 문제 푸는 챌린지를 시작한게 8월 7일이고 1레벨 문제를 다 풀었을 시점이 8월 23일(약 2주)이니 8월 23일 부터 11월 15일까지 자바스크립트 2레벨 문제들을 모두 푸는데 약 3개월의 시간이 걸린 것 같다.

중간 중간 문제가 추가 되긴 했지만 이리도 오래 걸린건 너무 뼈아프다.

몇가지 문제점을 찾자면

1. 알고리즘 문제풀이를 즐기지 않는점(하루 1문제 이상 풀기가 너무 싫었다.)
2. 내가 잘못하는 영역의 알고리즘 문제가 많았던점(그래프 탐색, 플로이드 워셜, 다익스트라 등)

정도 있을거 같다. 1레벨도 나름 소득이 있었지만 2레벨 문제들은 그 난이도가 확실히 1레벨 보다 많이 높았고, 전문적인 알고리즘에 대한 이해나 지식이 없이는 풀기 어려운 문제들이 많았다. 그로인해서 내가 모르는 부분들을 공부하는데 시간을 많이 소요해야했고, 부족한 영역들에 대해서 확실하게 인지하게 되어서 좋았다. 수학적인 부분이나, 알고리즘과 자료구조에 대해서 생각해볼만한 점들이 많았으니 나름 유익한 시간이였다고 평가 할 수 있다. 내가 원하는 만큼 코드 퀄리티를 끌어올리기 힘들다는 것에 스트레스를 많이 받긴했지만 ㅜㅜ

2레벨 문제를 다 풀고도 2레벨 자체가 난이도가 균일하지 않아서 2레벨 문제들 뭐가 나와도 다 쉽게 풀 수 있다고 장담할 수 없다는게 조금 아쉬운점인 것같다. 내가 푼 문제들과 비슷한 유형 문제가 나온다고 확실히 풀 수 있다고 장담할 수 없다.

지금 당장 3레벨을 들어가는 것은 시간 효율이 떨어지므로 이 챌린지는 이제 비정기적인 방식으로 지속해야겠다.
무엇보다 더 진행하기에는 알고리즘 풀이가 너무 괴롭고 재미없다. 개인적으로 하기 싫은 것을 할때 효율이 매우 떨어지는 성향이니 다시 알고리즘 풀이에서 소소한 즐거움을 얻을 수 있을때 까지 사이드 프로젝트나 다른 것들을 공부해야겠다.

현 시점에서 프로그래머스 1레벨, 2레벨, 자바스크립트 문제를 모두 풀었을때 총 문제 수는 118문제이고, 1481점이다.

드디어 해방!

문제

https://programmers.co.kr/learn/courses/30/lessons/12973

코딩테스트 연습 - 짝지어 제거하기

짝지어 제거하기는, 알파벳 소문자로 이루어진 문자열을 가지고 시작합니다. 먼저 문자열에서 같은 알파벳이 2개 붙어 있는 짝을 찾습니다. 그다음, 그 둘을 제거한 뒤, 앞뒤로 문자열을 이어 붙

programmers.co.kr

프로그래머스 레벨2 문제 - peulogeulaemeoseu lebel2 munje
프로그래머스 레벨2 문제 - peulogeulaemeoseu lebel2 munje

풀이

package seohae.algorithm.level2;

import java.util.Stack;

/**
 * https://programmers.co.kr/learn/courses/30/lessons/12973
 */

public class Lesson_049_12973 {
    public static void main(String[] args) {
        Lesson_049_12973 lesson = new Lesson_049_12973();

        int[] a = new int[]{1,2,3};
        System.out.println(lesson.solution("baabaa"));
    }

    public int solution(String s) {
        int answer = 0;

        Stack<Character> stack = new Stack<>();

        for (int i = 0; i < s.length(); i++) {
            char target = s.charAt(i);

            if (!stack.isEmpty() && target == stack.peek()) {
                stack.pop();
            } else {
                stack.push(target);
            }
        }

        if (stack.isEmpty()) {
            answer = 1;
        }

        return answer;
    }
}

해당 문제는 짝이 맞다면 Stack 에서 pop 하고, 맞지 않다면 Stack 에 push 하는 로직이다. 문자열의 길이만큼 반복문을 돌리고, Stack에 원소가 남아있다면 짝이 맞지 않는 것이므로 answer 변수에 1을 셋팅해준다.

[문제 설명]

조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다.

ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA

조이스틱을 각 방향으로 움직이면 아래와 같습니다.

▲ - 다음 알파벳
▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로)
◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
▶ - 커서를 오른쪽으로 이동

예를 들어 아래의 방법으로 "JAZ"를 만들 수 있습니다.

- 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다.
- 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다.
- 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다. 따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.

만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요.

<제한 사항>

name은 알파벳 대문자로만 이루어져 있습니다.

name의 길이는 1 이상 20 이하입니다.

<입출력 예>

name return
"JEROEN" 56
"JAN" 23

>문제 풀이

조이스틱을 상하 좌우로 움직여서 입력받은 String name을 최소로 몇 번 만에 만들 수 있는지 구해야합니다.

이 문제는 최소한의 좌우 조작 횟수를 어떻게 구할지가 관건이었습니다.

만약 "BBBAAB" 의 경우에 BBBAAB -> BBBAAB 이와 같은 순서로 움직일 때 최소 횟수가 나옵니다.

근데 이 문제가 테스트 케이스가 좀 부족하다고 느낀게 위에 제가 예시로 든 "BBBAAB"의 경우 답이 8이라고 생각되는데, 9로 출력되는 코드의 경우에도 채점을 통과합니다.

그래서 풀어놓고도 풀이하는데 오래 걸린 것 같습니다..ㅎㅎ.;;ㅜ

입력받은 name에 A가 포함되어 있다면 A가 가장 긴 부분을 기준으로 좌우 조작을 하는게 최소값이 나올 것으로 생각했는데, 이경우

1) 오른쪽으로 쭉 갔다가 "AA~A"를 만나면 다시 index=0으로 돌아오고, 뒤로 가서 "AA~A"를 만난다.

2) 뒤로 가서 "AA~A"를 만나면 다시 index=0로 돌아오고, 오른쪽으로 가서 "AA~A"를 만난다.

두가지 방법이 있습니다.

즉 name.length()-1 / 1번 / 2번 중에 최소값이 좌우조작의 최소횟수 인거죠.

*근데 문제의 테스트 케이스에는 1번 2번에 대해 처리가 달라도 정답이 되는 것 같습니다.

(제가 문제를 잘못 이해한 건가요.. 일단 내일 일어나서 다시 살펴봐야 할 것 같습니다.)

+수정하겠습니다.) 문제를 다시 읽어보니까 ◀:커서가 왼쪽으로 이동할 때, 첫번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서 라는 조건은 있지만, ▶:커서가 오른쪽으로 이동할 때, "마지막 위치에서 오른쪽으로 이동하면 첫번째 문자에 커서"라는 조건은 없습니다!

즉, "BBBAAB" 의 경우에 BBBAAB -> BBBAAB 이와 같은 순서로 움직일 때 최소 횟수가 나옵니다. (=9회)

왼쪽 화살표의 조건을 읽고 오른쪽도 같은 조건이라고 생각했었네요...(역시 정신이 똘망똘망 할 때 풀어야하나 봅니다..ㅎㅎ)

>전체 코드

import java.util.*;
class Solution {
    public int solution(String name) {
        int answer = 0;
        char d;
        
        for(int i=0; i<name.length(); i++){
            d= name.charAt(i);
            answer+=Math.min(d-'A', Math.abs('A'+26-d));
        }
        
        int minlen= name.length()-1;
        int end, cnt;
        for(int i=0; i<name.length(); i++){
            if(name.charAt(i)=='A') continue;
            end= i+1;
            while(end<name.length()&&name.charAt(end)=='A'){
                end++;
            }
            cnt=i*2+(name.length()-end);
            minlen= Math.min(minlen, cnt);
        }
        
        return answer+minlen;
    }
}

https://programmers.co.kr/learn/courses/30/lessons/42860

코딩테스트 연습 - 조이스틱

조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다. ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA 조이스틱을 각 방향으로 움직이면 아래와 같습니다. ▲ - 다

programmers.co.kr

프로그래머스 레벨2 문제 - peulogeulaemeoseu lebel2 munje