14일차 2024.11.03(알고리즘 5일차)

칙촉·2024년 11월 3일

🎯시작 전 목표

1.알고리즘 문제 풀기

💻Today I learned

- 대충 만든 자판

가장 처음 작성했던 코드는 이렇다.

class Solution {
    public int[] solution(String[] b, String[] e) {
        int[] a = new int[26];
        int[] d= new int[e.length];
       
        for( int i=0;i<b.length;i++)
        {
            int cnt=1;
            for(char c : b[i].toCharArray())
            {
                if(a[c-'A']>cnt || a[c-'A']==0) a[c-'A']=cnt;
                cnt++;
            }
        }
      
        for(int i=0;i<e.length;i++)
        {
            for(char c:e[i].toCharArray())
            {
                d[i]+= a[c-'A'];
            }
            if(d[i]==0) d[i]=-1;
        }   
        return d;
    }
}

각 알파벳 대문자의 아스키 코드에 해당하는 인덱스에 키맵의 최솟값을 넣어주고, 모두 더해 단어를 입력하는 총 횟수를 구하는 방법이다.
그런데 이게 왠걸?

내 완벽한 줄만 알았던 코드가 56.5점밖에 안되는 반푼이였다니..
고심한 끝에 나는 지금껏 문제를 몇 번 해결해주기도 했고, 이 문제에 더없이 어울리기도 한 Hashmap을 이용하기로 했다.
그렇게 개선된 코드는 이렇다.

import java.util.*;
class Solution {
    public int[] solution(String[] b, String[] e) {

        HashMap<Character,Integer> a = new HashMap<>();
        int[] d = new int[e.length];
     
        for( int i=0;i<b.length;i++)
        {
            int cnt=1;
            for(char c : b[i].toCharArray())
            {
                if(!a.containsKey(c)) a.put(c,cnt);
                else if(a.get(c)>cnt) a.replace(c,cnt);
                cnt++;
            }
        }
        for(int i=0;i<e.length;i++)
            for(char c:e[i].toCharArray())
            {
                if(a.containsKey(c)) d[i]+= a.get(c);
        {
            }
            if(d[i]==0) d[i]=-1;
        } 
        return d;
    }
}

이번에야말로 완벽하다 생각했으나 프로그래머스의 생각은 달랐나보다.

반푼이였던 녀석이 실행시간만 늘어난 채 더 반푼이가 되어 돌아왔다.
나는 코드 자체에 어떠한 문제가 있음을 깨닫고 1시간가량 코드만 뚫어져라 보다 잘못된 깨달았다.
단어에 든 알파벳의 최솟값을 모두 더했을 때 0인 단어를 작성이 불가능한 단어라 판단하고 -1을 저장했는데,
실은 단어중 1개만 키맵에 없는 단어일 경우 모든 최솟값을 더한 값이 0이 나오지 않는다는 사실이다.
별 것도 아닌걸 깨닫는ㄷ까진 생각보다 오랜 시간이 걸렸지만, 끝내 간과했던 부분을 찾게 되어 개선하게 된 코드는 이렇다.

import java.util.*;

class Solution {
    public int[] solution(String[] b, String[] e) {
  		//대문자 알파벳을 key로 최솟값을 value로 가진 HashMap이다.
        HashMap<Character,Integer> a = new HashMap<>(); 
        int[] d = new int[e.length]; //최솟값을 더한 수를 각 단어에 대응시킨 배열이다.

        for( int i=0;i<b.length;i++)
        {	//키의 최솟값을 구하기 위해 키맵의 수만큼 반복한다.
            int cnt=1;
            for(char c : b[i].toCharArray()) //각 키맵이 가진 알파벳 수맞큼 반복,
            {		//각 알파벳을 키로 가진 현재cnt를 value로 넣는다.
                if(!a.containsKey(c)) a.put(c,cnt); //이미 존재하는 키의 value가
                else if(a.get(c)>cnt) a.replace(c,cnt); //cnt보다 크다면 갱신한다.
                cnt++; //현 키맵에서의 타수를 의미하기 때문에 모든 조건에서 벗어나도 1 늘린다.
            }
        } //이번엔 단어의 최소 타수를 구하기 위해 단어의 수만큼 반복한다.
        for(int i=0;i<e.length;i++)
            for(char c:e[i].toCharArray()) //각 단어의 글자수만큼 반복해,
            {	//해당 알파벳을 HashMap이 Key로 가지고 있을 시, Value만큼 더한다.
                if(a.containsKey(c)) d[i]+= a.get(c);
                else //그렇지 않을 시 단어는 절대 완성될 수 없으므로 -1을 저장 후 탈출한다.
                {
                    d[i]=-1;
                    break ;
                }   
        }
        return d;
    }
}

드디어 못난 아빠 밑에서 100점짜리 아들이 탄생하는 감격적인 순간을 맞이할 수 있었다.

덤으로 처음 배열로 짰던 코드가 실행시간이 더 적었던 게 생각나 똑같이 개선해 제출해보았다.

class Solution {
    public int[] solution(String[] b, String[] e) {
        int[] a = new int[26];
        int[] d= new int[e.length];

        for( int i=0;i<b.length;i++)
        {
            int cnt=1;
            for(char c : b[i].toCharArray())
            {
                if(a[c-'A']>cnt || a[c-'A']==0) a[c-'A']=cnt;
                cnt++;
            }
        }
        for(int i=0;i<e.length;i++)
        {
            for(char c:e[i].toCharArray())
            {
                if(a[c-'A']!=0)d[i]+= a[c-'A'];
                else
                {
                    d[i]=-1;
                    break;
                }       
            }
        }
        return d;
    }
}

실제로 문제도 통과하고 실행시간도 개선된 120점짜리 아들이 탄생했다.

profile
강세민

0개의 댓글