내 맘대로 알고리즘

[프로그래머스 알고리즘] 전화번호 목록 JAVA


1. 문제


https://programmers.co.kr/learn/courses/30/lessons/42577?language=java 


문제 설명

전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.

  • 구조대 : 119
  • 박준영 : 97 674 223
  • 지영석 : 11 9552 4421

전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.

제한 사항
  • phone_book의 길이는 1 이상 1,000,000 이하입니다.
  • 각 전화번호의 길이는 1 이상 20 이하입니다.
입출력 예제
phone_bookreturn
[119, 97674223, 1195524421]false
[123,456,789]true
[12,123,1235,567,88]false
입출력 예 설명

입출력 예 #1
앞에서 설명한 예와 같습니다.

입출력 예 #2
한 번호가 다른 번호의 접두사인 경우가 없으므로, 답은 true입니다.

입출력 예 #3
첫 번째 전화번호, “12”가 두 번째 전화번호 “123”의 접두사입니다. 따라서 답은 false입니다.

출처


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
import java.util.HashMap;
 
/**
     * @author gamjatwigim
     * @date 2018.12.25
     * @url: https://gamjatwigim.tistory.com/
     * @algorithm : https://programmers.co.kr/learn/courses/30/lessons/42577?language=java
     * @content:
     * 문제 설명
        전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
        전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.
        
        구조대 : 119
        박준영 : 97 674 223
        지영석 : 11 9552 4421
        전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 
        어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.*/
public class Programmers2 {
    boolean flag = true;
    public boolean solution(String[] phone_book) {
        int min=99999;//최소값은 phone_book의 접두사를 얻어내기 위해서 null값이 나오지 않도록 한다.
        HashMap<String,Integer> resultHash = new HashMap();//hashMap을 통해 key 값에 접근할 것 이다.
        for(int i=0; i<phone_book.length; i++) {
            min = Math.min(min, phone_book[i].length());
            resultHash.put(phone_book[i], 0);//값을 초기화
        }
        for(int j=0; j<phone_book.length;j++) {
            if(resultHash.get(phone_book[j].substring(0, min).toString())!=null) {
                //접두사가 존재할 경우에 해당 value값에 +1 값을 함.
                //따라서 정상적인 값이면 value는 모두 1
                resultHash.put(phone_book[j].substring(0, min), resultHash.get(phone_book[j].substring(0, min).toString())+1);
            }
        }
        
        resultHash.forEach((k,v)->{
            //hash를 검사함.
            //value가 1보다 크면 접두사로 사용.
            if(v>1) {
                flag = false;
            }
        });
        return flag;
    }
}
cs


고려한 사항.


1. 접두사에 접근하기 위해선 어떻게 해야할까?

2. 각종 null 값을 체크는 어떻게 해야할까?


2.1. 접두사에 접근하기 위해선 어떻게 해야할까?

처음에는 배열을 통해서 값을 접근하려고 했었습니다.

하지만 그렇게 하기 위해서는 2중 for문을 사용해야한다는 생각을 하게 되었습니다.

그리고 또한 substring을 하면서 생기는 각종 null값에 취약했습니다.


그래서 Hash로 구조를 짜야겠다고 생각했습니다.


2.2 null값은 어떻게 고려햐지?

key값들의 length 길이 값이 일정하지 않았고, 이것을 해결하기 위해서 substring을 하는 길이를

모든 key값들의 min 값을 구해서 substring을 하게 된다면 null이 나오지 않는다고 생각을 하게 되었습니다.


2.3. 따라서 resultHash.get(phone_book[j].substring(0,min) 이 null이 아니라면 어떤 값이 존재하는 것이고,

그 중에서는 무조건 자기 자신을 가리키기 때문에 그 값은 1이 될 것입니다.

하지만 그 외에 접근하게 되면, 접두사의 조건으로 접근하기 때문에 1초과의 값을 갖게 되면

접두사로 사용되었다는 것을 의미합니다.


라고 생각을 하고, Run 시켰을 때도 잘 됐지만, 여자친구가 82 72 12345 123456 이라는 테스트 예제가 있다면 될까?

라고 하고, 해당 테스트 예제대로 돌려보니 안 되었다.

해당 hash로 접근하는 것은 접미사가 min의 길이에서 나온다는 조건에서만 됐고,

이것을 오류없이 처리하기 위해서는 위의 것들이 필요가 없었다.


결국 다시 고려한 사항

1. null 처리 없이 substring을 사용해라.

2. hash에서 벗어나자.


였고 null 처리 없이 특정 텍스트가 string의 시작지점에 있는 지 확인하기 위해서 String.startsWith(string)이라는 매소드를

통해서 쉽게 해결했고, 결과 값이 걸리면 break로 빠져나가게 했더니 잘 되었다...


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
import java.util.HashMap;
 
/**
     * @author gamjatwigim
     * @date 2018.12.25
     * @url: https://gamjatwigim.tistory.com/
     * @algorithm : https://programmers.co.kr/learn/courses/30/lessons/42577?language=java
     * @content:
     * 문제 설명
        전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
        전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.
        
        구조대 : 119
        박준영 : 97 674 223
        지영석 : 11 9552 4421
        전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 
        어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.*/
public class Programmers2 {
    boolean flag = true;
    int count = 0;
    public boolean solution(String[] phone_book) {
        flag = true;
        for(int i=0; i<phone_book.length;i++) {
            for(int j=0; j<phone_book.length; j++) {
                if(!phone_book[i].equals(phone_book[j])&&phone_book[i].startsWith(phone_book[j])) {
                    flag = false;
                    break;
                }
            }
            if(flag==false)
                break;
        }
        
        return flag;
    }
}
cs