[문제풀이] 자동완성

업데이트:

2018 Kakao Blind Recruitment 기출 문제

문제 링크 : 자동완성

풀이 시간 : 25분

1. 문제 풀이

자동 완성에 필요한 접두어을 찾아서 각 접두어들의 길이를 더해주는 문제

단어의 접두어를 쉽게 찾기 위해서는 Trie 구조를 이용하였다.

1) root node를 만들어 모든 단어들을 Trie 구조에 맞게 저장한다.

2) 저장할 때 각 node를 몇번 거쳐 가는지를 저장한다.

3) root node부터 하위 node를 돌면서 자동 완성에 필요한 접두어들의 길이를 찾는다.

2. 소스 코드

    static public int solution(String[] words) {
		int answer = 0;
		// Trie 자료구조 root
		Node root = new Node('0');
		for (int i = 0; i < words.length; i++) {
			// 각 단어 시작 시 root에서 시작
			Node curr = root;
			for (int j = 0; j < words[i].length(); j++) {
				// 각 node에 현재 알파벳가 있는 검사
				if (!curr.hm.containsKey(words[i].charAt(j))) {
					// 없으면 hashMap에 넣어 만들어 준다.
					curr.hm.put(words[i].charAt(j), new Node(words[i].charAt(j)));
				}
				// 지나갈때마다 증가
				curr.num++;
				// 다음 알파벳 node로 이동
				curr = curr.hm.get(words[i].charAt(j));
			}
			// 마지막 단어가 끝나면 그곳도 방문하므로
			curr.num++;
			// 끝에는 '0'으 넣어서 단어 끝이라고 표시
			curr.hm.put('0', null);
		}
		// Trie 구조를 돌면서 자동 완성에 필요한 단어 길이를 검색
		answer = search(0,root);
		return answer;
	}
	static int search(int deep, Node node) {
		if(node == null) {
			// node가 없으면 단어가 끝까지 왔다는 소리
			// 접두어 없이 단어 자체를 다 써야 자동 완성이 된다는 것이다
			// 단어 끝에 '0'을 넣었기 때문에 deep에서 -1
			return deep-1;
		}else if(node.num==1) {
			// 이 다음부터는 한번만 왔기 때문에
			// 이때부터 자동완성이 가능한 접두어 가능
			return deep;
		}else {
			int sum = 0;
			// node.num이 1이 아니기 때문에
			// node의 하위를 검색하면서 하위에서 가능한 자동완성 길이를 더해준다.
			Iterator<Character> iter = node.hm.keySet().iterator();
			while(iter.hasNext()) {
				sum +=search(deep+1,node.hm.get(iter.next()));
			}
			return sum;
		}
	}
	static class Node {
		// 알파벳
		char c;
		// 이 node를 지나치는 횟수
		int num;
		// 하위 node
		HashMap<Character, Node> hm;

		Node(char c) {
			this.c = c;
			this.num = 0;
			this.hm = new HashMap<Character, Node>();
		}
	}

3. 후기

최근에 공부한 Trie 구조를 사용해 보았다.

Trie 구조

M : 문자열 개수

L : 가장 긴 문자열의 크기

트리 생성 O(M*L)

탐색 O(L)