카카오 신입공채 3차 코딩테스트 문제5 자동완성 JAVA Tire구현
- JAVA/알고리즘과 자료구조
- 2018. 4. 21. 00:56
카카오 신입공채 3차 코딩테스트 문제5 자동완성 JAVA Tire구현
이 블로그를 만든 계기가 카카오 신입공채 코딩테스트의 문제 수준을 보고 깊은 자기반성의 끝에 블로그를 개설하고 알고리즘 문제를 풀어보고자 마음먹었습니다. 드디어 그 시작이자 마지막 문제인 자동완성 문제입니다. 문제설명은 다음과 같습니다.
각 문자를 리턴받기 위해서 몇번의 타이핑을 해야 하는지 구하는 문제입니다. 아래는 출력형식과 입출력 예제 입니다.
출처 : http://tech.kakao.com/2017/11/14/kakao-blind-recruitment-round-3/
카카오 자동완성 문제 JAVA 예제
문제 해설을 보면 본 문제는 일반적인 스트링 비교로 풀게되면 테스트 케이스에서 타임오버가 나오게 됩니다. 우선 가장 심플하게(무식하게) 풀어본 스트링 비교로 풀어본 버젼입니다. 3중 for문 까지 쓰게 되었으니 최소 n^3의 시간복잡도를 갖게 될 것 같습니다. 그래도 우선 테스트 케이스의 결과는 정상적으로 출력됩니다.
자동완성 무식한 버젼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public static int count(String[] arr) { int keyConut = 0; int matchCount = 0; for(String key : arr) { String subKey; for(int i = 1 ; i <= key.length() ; i++) { subKey = key.substring(0, i); // subKey를 받아볼때마다 count++로 간주 keyConut++; matchCount = 0; // subKey를 입력된 배열과 startWith로 검사하여 오직 한개가 나오는지 검사 for(String target : arr) { if(target.startsWith(subKey)) { matchCount++; } } // 검색결과가 한개가 나오면 다음문자로 넘어감 if(matchCount == 1) { break; } } } return keyConut; } | cs |
아무래도 마음이 편치 않아서 자동완성 문제를 Trie자료구조를 이용하여 구현해본 예제 입니다. 다른 분 소스를 조금 참고하려고 해도 대부분 다른 블로거 분들은 카카오 코딩테스트 1일차만 남기셔서 레퍼런스를 찾기 힘들어 직접 구현해 보았습니다.
자동완성 JAVA Trie구현 버젼
Trie를 선언하고 데이터 입력하고 count를 구하는 소스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public static int count(String[] arr) { // Trie 데이터 입력 Trie trie= new Trie(); for(String str : arr) { trie.insert(str); } // 입력 데이터 별 카운트 int count = 0; for(String str : arr) { for(int i = 1 ; i <= str.length() ; i++) { count++; String word = str.substring(0, i); // 한글자씩 늘려서 나오는 노드가 1개인 경우 더이상 진행하지 않음 if(trie.findLeafs(word).size() == 1) { break; } } } return count; } | cs |
아래는 Trie 자료구조를 구현한 소스
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | private static class Trie { TrieNode root; public Trie() { root = new TrieNode(' '); } /** * Trie에 문자열 입력 * @param word */ public void insert(String word) { TrieNode current = root; for(char c : word.toCharArray()) { if(current.getChild(c) != null) { current = current.getChild(c); } else { current = current.putChild(c); } } current.setLeaf(true); } /** * 문자열 word까지 입력된 경우 리턴되는 모든 leaf 리턴 * @param word * @return */ public ArrayList<TrieNode> findLeafs(String word) { ArrayList<TrieNode> retList = new ArrayList<TrieNode>(); TrieNode current = root; //입력된 word에 해당하는 마지막 TrieNode를 탐색 for(char c : word.toCharArray()) { if(current.getChild(c)!=null) { current = current.getChild(c); } else { retList.clear(); return retList; } } // 마지막 TrieNode가 leaf이면 추가 if(current.isLeaf()) { retList.add(current); } // 현재 TrieNode에 연결된 자식노드들의 모든 leaf를 추가 retList.addAll(current.getAllLeaf()); return retList; } } private static class TrieNode { private char data; private boolean isLeaf; private HashMap<Character, TrieNode> children; public TrieNode(char c) { this.data = c; children = new HashMap<Character, TrieNode>(); isLeaf = false; } public HashMap<Character, TrieNode> getChildren() { return children; } public boolean isLeaf() { return isLeaf; } public void setLeaf(boolean isLeaf) { this.isLeaf = isLeaf; } /** * 입력 c에 해당하는 TrieNode 생성 후 Child로 추가 * @param c * @return */ public TrieNode putChild(char c) { TrieNode temp = new TrieNode(c); getChildren().put(c, temp); return temp; } /** * 현재 노드의 자식노드 중 입력값 c에 해당하는 값 리턴 * @param c * @return */ public TrieNode getChild(char c) { return getChildren().get(c); } /** * 현재 노드와 연결된 모든 자식노드 중 leaf에 해당하는 노드 전부 리턴 * @return */ public ArrayList<TrieNode> getAllLeaf() { ArrayList<TrieNode> retList = new ArrayList<TrieNode>(); for(TrieNode child : getChildren().values()) { if(child.isLeaf()) { retList.add(child); } retList.addAll(child.getAllLeaf()); } return retList; } } | cs |
이것으로 카카오 신입공채 코딩테스트 문제를 모두 정리해 보았습니다. 생각모두 엄청나게 난이도가 높은 문제들이 많았습니다. 연차만 쌓이고 실력은 늘지 않는 것 같아서 답답할 때가 많았는데 심심할때마다 알고리즘 푸는 것도 굉장히 재미있네요.
'JAVA > 알고리즘과 자료구조' 카테고리의 다른 글
카카오 신입공채 3차 코딩테스트 문제4 방금그곡 JAVA (0) | 2018.04.20 |
---|---|
카카오 신입공채 3차 코딩테스트 문제3 파일명정렬 JAVA (0) | 2018.04.20 |
카카오 신입공채 3차 코딩테스트 문제2 LWZ압축 JAVA 예제 (0) | 2018.04.19 |
카카오 신입공채 3차 코딩테스트 문제1 N진수 게임 JAVA 예제 (2) | 2018.04.19 |
카카오 신입공채 1차 코딩테스트 문제7 추석트래픽 JAVA 예제 (0) | 2018.04.11 |
이 글을 공유하기