[프로그래머스-Java] 해시 3과 기초...

RedPanda·2022년 8월 9일
0

[알고리즘] Java

목록 보기
16/16

📌 전화번호목록

📃 설명

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

🔑 풀이

해시에 대해서 풀고 있음에도 잘 몰랐었다. 어쨋든 열심히 구상을 해보았다.
방법은 저번처럼 정렬해서 비교할 생각이었다.

1.배열을 sort해준다.
2.(배열의 길이-1) 만큼 반복을 한다.
3.반복자와 그 후의 값을 비교하여 앞글자가 포함되어 있으면 false를 반환한다.

해결하기 전에 알아가야할 Java 메소드의 사용법이 있다.

  • Arrays.sort() : string이면 사전순대로 정렬, int면 오름차순으로 정렬
  • String.startsWith(str) : str이 String 앞에 포함되어 있는지 비교

이 메소드만 알면 쉽게 풀 수 있는 문제이다. 여기까지 생각이 못미치긴 했지만...

import java.util.*;

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

기초~

해시를 풀다가 기초가 너무 없는 것 같아 완전 초심으로 돌아가서 풀어보았다.
푸는 도중에 이슈가 생긴 부분에 대해 이야기하고자 한다.

📌 하샤드 수

📃 설명

양의 정수 x가 하샤드 수이려면 x의 자릿수의 합으로 x가 나누어져야 합니다. 예를 들어 18의 자릿수 합은 1+8=9이고, 18은 9로 나누어 떨어지므로 18은 하샤드 수입니다. 자연수 x를 입력받아 x가 하샤드 수인지 아닌지 검사하는 함수, solution을 완성해주세요.

한창 백준을 풀 때는 잘 썼는데 이번에 생각도 못했던 split()을 복습하게 되었다.

class Solution {
    public boolean solution(int x) {
        boolean answer = true;
        String str_x = Integer.toString(x);
        int devide = 0;
        for(int i = 0; i < str_x.length(); i++){
            int tmp = str_x.charAt(i) - '0';
            devide += tmp;
        }
        if(x % devide != 0) answer = false;
        return answer;
    }
}

위 코드는 내가 작성한 코드이다.
문제를 풀면서 문자열을 어떻게 자를까 고민을 했었다. 아스키코드를 이용하여 해결하긴 했지만, split()에 ''인자를 넣으면 더 쉽게 문자열을 자를 수 있다.

📌 최대공약수와 최소공배수

프로그래밍 기초 수업에서 본 알고리즘이다.
이 문제는 외워지지가 않아서 할때마다 새롭다.

🔑 풀이

설명보다 바로 풀이로 넘어가겠다.
1부터 n 또는 m중에 작은 값까지 나눠보도록 해봤다.
그러나 4를 나눠야하는 경우에 2를 나누고 증가를 하면 2가 남아버리는 문제가 생겼다.

그래서 높은 수부터 나누게 했다.
n부터 1까지 감소하면서 최대공약수를 구했고, 최대공약수에 n과 m을 곱하여 최대공배수를 구했다.

class Solution {
    public int[] solution(int n, int m) {
        int[] answer = {};
        int a = Math.min(n,m);
        int gcd = 1;
        while(true){
            if(n % a == 0 && m % a == 0){
                n /= a;
                m /= a;
                gcd *= a;
            }
            if(a == 1){
                break;
            }
            a--;
        }
        int[] tmp = {gcd, gcd * n * m};
        answer = tmp;
        return answer;
    }
}

📌 정수 제곱근 판별

🔑 풀이

Math.sqrt(n)을 해서 정수이면 +1의 제곱을 해주면 되는 간단한 문제이다.
여기서 말하고자하는 것은 형변환이 되지 않으면 잘못된 값이 나온다는 것이다.

answer의 자료형은 long이기 때문에 double인 결과값을 long으로 강제 형변환해주었다.

class Solution {
    public long solution(long n) {
        double answer = -1;
        double div = Math.sqrt(n);
        if((div - (double)Math.floor(div)) == 0.0){
            answer = (div +1) * (div + 1);
        }
        return (long)answer;
    }
}

💬 여담

앞으로 nodeJS를 한다고 하니 JS의 기초도 닦으면서 Java도 같이 공부하도록 해야겠다.
둘다 효율적인 메소드가 많지만 처음 배울때 요령이라 생각하여 거의 쓰지 않았었다.

그러나 sort()만 보아도 반복문을 아무렇게나 사용하는 것보다 시간복잡도 면에서나 코드의 길이 면에서나 훨씬 효율적인 코딩을 할 수 있다.

물론 더 효율적인 알고리즘을 찾는 것이 중요하겠지만 어떤 방법이 효율적인지는 직접 사용해보고 판단하는 것이 맞다고 생각했다.

profile
끄적끄적 코딩일기

0개의 댓글