1) 문제
https://programmers.co.kr/learn/courses/30/lessons/42577
코딩테스트 연습 - 전화번호 목록
전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다. 전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다. 구조
programmers.co.kr
한 번호가 다른 번호의 접두어인 경우를 확인해야 한다.
접두어인 경우가 있으면 false 없으면 true
2) 풀이
단순히 생각하면 이중반복으로 두 번호를 뽑아서 다시 반복문으로 첫 번째 숫자부터 비교하면 되지 않을까?
문제는 해시를 사용하지 않는 다는 점과 반복문이 3중으로 들어간다는 점이다.
역시나 효율성 테스트는 모두 실패했다.
다시 해시를 사용하는 쪽으로 방향을 틀어서 고민을 해봤다.
3-1) 코드(실패)
bool solution(vector<string> phone_book) {
bool answer = true;
for(auto i=phone_book.begin(); i!=phone_book.end() ; i++) {
for(auto j=next(i,1); j!=phone_book.end(); j++) { //i 다음 번호부터 비교
if(i == j) continue;
if(i->length() < j->length()) { //i 번호의 길이가 j보다 짧을 경우에만
int idx=0;
for(idx=0; idx<i->length(); idx++) { // i와 j의 번호를 비교
if((*i)[idx] != (*j)[idx]) break;
}
if(idx == i->length()) answer = false;
}
}
}
return answer;
}
3-2) 코드(통과)
bool solution(vector<string> phone_book) {
unordered_map<string, int> hash_map;
for(int i=0; i<phone_book.size(); i++)
hash_map[phone_book[i]] = 1; //해시에 번호 저장
for(int i=0; i<phone_book.size(); i++) {
for(int j=0; j<phone_book[i].size()-1; j++) {
//첫 번째 글자부터 j+1 길이의 sub string 추출. 단 전체 string 길이의 -1까지
string phone_number = phone_book[i].substr(0,j+1);
if(hash_map[phone_number])
return false;
}
}
return true;
}
4) 정리
간단히 substr(pos, count)에서 pos는 첫 번째 문자의 위치, count는 부분 문자열의 길이
해시를 이용하는 경우 쉽게 해결할 수 있는 문제였다.
문제를 풀면서 찾아보니 sort/loop로도 통과할 수 있었다.
string을 sort로 정렬하는 경우 사전 정렬이 되기 때문에 현재 대상과 다음 대상의 비교만 하면 된다.
위 블로그에서는 [0]이 [2]의 접두어라면 [1]도 [2]의 접두어라는 것이 보장된다고 했지만 사실 그렇지는 않다.
반박 예시 = {"1", "1234", "13"}
다만 [0]이 [1]의 접두어가 아니라면 [1]이후의 모든 요소에서 접두어가 될 수 없기 때문에 [0]은 [1]만 비교하면 된다.
그래서 이 블로그에서 제시하는 이 solution이 가능하다.
bool solution(vector<string> phone_book) {
// 1. phoneBook 배열을 정렬한다.
sort(phone_book.begin(), phone_book.end());
for(auto i : phone_book) {
cout << i << endl;
}
// 2. 1중 Loop을 돌며 앞 번호가 뒷 번호의 접두어인지 확인한다.
for (int i = 0; i < phone_book.size() - 1; i++)
if (phone_book[i + 1].find(phone_book[i]) == 0) return false;
// 3. 여기까지 오면 접두어가 없다는 것이다.
return true;
}
여기서 사용된 find함수는 string에서 특정 string을 찾으면 그 위치를 반환해준다. 찾는 문자열이 없는 경우 -1을 리턴한다.
'Algorithm' 카테고리의 다른 글
| [프로그래머스] 푸드 파이트 대회 (0) | 2022.11.09 |
|---|---|
| [프로그래머스] 신규 아이디 추천 (0) | 2022.07.05 |
| [프로그래머스] 문자열 압축 (0) | 2022.04.01 |
| [Codility] MissingInteger - demo test (0) | 2022.03.29 |
| [프로그래머스] 완주하지 못한 선수 (0) | 2022.03.05 |