1.알고리즘 문제 풀기
- 대충 만든 자판
가장 처음 작성했던 코드는 이렇다.
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점짜리 아들이 탄생했다.