Tiny Middle Finger

카테고리 없음

코테준비(JAVA) - 해시(정렬)

니 성적 C 2024. 9. 19. 17:43
728x90
반응형

문제 설명

 

전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.
구조대 : 119
박준영 : 97 674 223
지영석 : 11 9552 4421
전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.

제한 사항

phone_book의 길이는 1 이상 1,000,000 이하입니다.
각 전화번호의 길이는 1 이상 20 이하입니다.
같은 전화번호가 중복해서 들어있지 않습니다.

입출력 예제

phone_book return
["119", "97674223", "1195524421"] false
["123","456","789"] true
["12","123","1235","567","88"] false

입출력 예 설명

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

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

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

728x90

풀이과정

처음 풀이는 사실 JAVA가 아니라 C++로 하였다. substring을 이용하여 풀이를 하였으나 결국엔 틀렸으니 C++코드는 추후 다루도록 해볼게요.

자바에서 처음 짠 코드는 substring을 이용한 이중 for문 구조였습니다.

맨 처음 코드

class Solution {
   public boolean solution(String[] phone_book) {
       Arrays.sort(phone_book);
       int len = phone_book.length();
       
     for(int i = 0;i<len - 1;i++){
           for(int j = i;j<len;j++){
               if(phone_book[i].substring(0,2).eqals(phone_book[j].substring(0,2)){
                   boolean answer = false;
                   return answer;
               }
               else{
                   boolean answer = true;
                   return answer;
               }
           }
       }
   }
}

이 코드에서 처음 오류가 발생한 부분은 return answer부분이었어요.
자바는 모든 경우에서의 반환값이 있어야하기 때문에 answer 선언을 밖으로 빼주고 코드 맨 마지막에 return을 했습니다.

첫번째 수정

class Solution {
    public boolean solution(String[] phone_book) {
        Arrays.sort(phone_book);
        int len = phone_book.length();
        boolean answer = true;
        loop:
        for(int i = 0;i<len - 1;i++){
            for(int j = i;j<len;j++){
                if(phone_book[i].substring(0,2).eqals(phone_book[j].substring(0,2)){
                    answer = false;
                    break loop;
                }
                else{
                    answer = true;
                    
                }
            }
        }
        return answer;
    }
}

여기서 false가 나왔을 때 바로 break를 해주기 위해 이중 for문 위에 loop:를 붙여준 후 break loop;를 하여 loop가 붙은 for문을 바로 탈출하게 해주었어요.
이 코드는 시간이 많이 걸리고 효율이 좋지 않은 코드일 뿐더러 정답률이 54%가량 밖에 나오지 않았습니다.
그래서 다시 수정하기로 했습니다.
가장 첫번째 문제는 정렬을 했음에도 불구하고 n^2의 성능을 가지고 있다는 점, 정렬을 했음에도 값을 모두 비교하고 있었던 점이었어요.
그리고 친구(?)를 통해 자바에는 startsWith()와 endsWith()라는 좋은 함수가 있다는 것을 배웠습니다... 나의 헛고생..

두번째 수정이

import java.util.Arrays;

class Solution {
    public boolean solution(String[] phone_book) {
      
         Arrays.sort(phone_book);
	        int len = phone_book.length;
	        boolean answer = true;
	       
	      
	        for(int i = 0;i<len - 1;i++){
	            String str1 = new String(phone_book[i].substring(0,2));
	            String str2 = new String(phone_book[i+1].substring(0,2));
	           if(str1.startsWith(str2)) {
	        	   answer = false;
	        	   break;
	           }
	        }
	       
	        return answer;
    }
}

갑자기 엄청나게 간결한 코드가 나왔죠. 여기서 예제는 모두 통과!!
하지만 제출 후 채점은 처참히 54%.. 런타임 에러가 계속해서 떴죠.
startWith()를 쓸 때 접두어를 정확히 하기위해선 앞 두 글자를 비교해줘야겠다! 라는 생각에 substring을 사용했는데 여기서 큰 문제가 발생합니다.
똑똑한 사람들은 눈치 채셨겠지만 제한 사항을 보시면 최소가 1입니다. 두번째 글자가 없을 수도 있다는 말입니다.
그래서 결국 최최최종 수정을 하였습니다.

최최최종 수정

import java.util.Arrays;

class Solution {
    public boolean solution(String[] phone_book) {
      
         Arrays.sort(phone_book);
	        int len = phone_book.length;
	        boolean answer = true;
	       
	      
	        for(int i = 0;i<len - 1;i++){
	           if(phone_book[i+1].startsWith(phone_book[i])) {
	        	   answer = false;
	        	   break;
	           }
	        }
	       
	        return answer;
    }
}

여기서 if안에 함수를 넣어 boolean 값을 판별하고 answer의 값을 넣어주는 이유는
answer = phone_book[i+1].startsWith(phone_book[i]); 하고 if문에서 answer를 판단할 경우

answer = phone_book[i+1].startsWith(phone_book[i]);
if(answer){
	answer = false;
	break;
}

같은 접두어가 있어도 false, 같은 접두어가 없어도 false가 되어 오류가 발생하기 때문입니다.
만약 변수에 넣어 비교를 하고 싶다면 새로운 boolean값을 선언해야 합니다.

아직 자바의 함수 startsWith()와 endsWith()는 익숙하지 않아 이 개념은 따로 올려보도록 할게요.

반응형

 

728x90
반응형