1️⃣ 하샤드 수 

 

문제 설명

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

제한사항

  • x는 1 이상, 10000 이하인 정수입니다.

입출력 예

x answer
10 true
12 true
11 false
13 false

 

입출력 예 #1
10의 모든 자릿수의 합은 1입니다. 10은 1로 나누어 떨어지므로 10은 하샤드 수입니다.

입출력 예 #2
12의 모든 자릿수의 합은 3입니다. 12는 3으로 나누어 떨어지므로 12는 하샤드 수입니다.

입출력 예 #3
11의 모든 자릿수의 합은 2입니다. 11은 2로 나누어 떨어지지 않으므로 11는 하샤드 수가 아닙니다.

입출력 예 #4
13의 모든 자릿수의 합은 4입니다. 13은 4로 나누어 떨어지지 않으므로 13은 하샤드 수가 아닙니다.

 

💻 나의 풀이

class Solution {
    public boolean solution(int x) {
        int sum = 0;
        int n = x;
        
        while (n != 0) {
            sum += n % 10;   // 각 자릿수 구해서 sum 에 더하기
            n /= 10;   // 다음 자릿수로 넘어가기
        }
        
        return x % sum == 0? true : false;
    }
}

 

문제를 보고 각 자릿수를 나누기 위해 두 가지 방법이 떠올랐습니다.

첫번째 방법은 위 처럼 10을 나눈 나머지로 각 자릿수를 구하고, 다시 나누어서 다음 자릿수로 넘어가는 것을 반복해서 자릿수를 구하는데 n이 0이 아닐 동안만 반복하면 됩니다.

 

public class HarshadNumber{
    public boolean isHarshad(int num){

        String[] temp = String.valueOf(num).split("");

        int sum = 0;
        for (String s : temp) {
            sum += Integer.parseInt(s);
        }

        if (num % sum == 0) {
            return true;
        } else {
            return false;
        }
    
    }

}

 

두 번째 방법은 String.valueOf() 메소드를 이용해 문자열로 바꾼 후, split() 메소드를 통해 하나씩 분리해주는 방법입니다.

각 자릿수를 문자열 배열 temp를 생성해 저장합니다.

그 이후, 배열 temp의 각 요소를 순회하면서 Integer.parseInt()를 사용하여 문자열을 정수로 변환하고, 그 값을 sum에 누적합니다.

 


 

2️⃣ 두 정수 사이의 합

 

문제 설명

두 정수 a, b가 주어졌을 때 a와 b 사이에 속한 모든 정수의 합을 리턴하는 함수, solution을 완성하세요.
예를 들어 a = 3, b = 5인 경우, 3 + 4 + 5 = 12이므로 12를 리턴합니다.

제한사항

  • a와 b가 같은 경우는 둘 중 아무 수나 리턴하세요.
  • a와 b는 -10,000,000 이상 10,000,000 이하인 정수입니다.
  • a와 b의 대소관계는 정해져있지 않습니다.

입출력 예

a b return
3 5 12
3 3 3
5 3 12

 

 

💻 나의 풀이

class Solution {
    public long solution(int a, int b) {
        long answer = 0;
 
        if (a <= b) {
            for (int i = a; i <= b; i++)
                answer += i;
        } else {
            for (int i = b; i <= a; i++)
                answer += i;
        }
 
        return answer;
    }
}

 

이 문제도 두 가지 방법이 떠올랐는데

첫 번째는 a가 b보다 작거나 같을 경우엔 ( 예를 들어 a=3, b=5 ) a부터 b까지 순회하면서 1씩 커지는 i의 합을 누적.

a가 b보다 클 경우엔 ( 예를 들어 a=5, b=3 ) b부터 a까지 순회하면서 마찬가지로 1씩 커지는 i의 합을 누적해주는 방법 입니다.

 

class Solution {
    public long solution(int a, int b) {
        long answer = 0;
        
        int min = Math.min(a,b);
        int max = Math.max(a,b);
        
        if(a == b) {
            answer = a;
        } else {
            for (int i = min; i <= max; i++) {
                answer += i;
            }
        }
        
        return answer;
    }
}

 

두 번째 방법은 Math 클래스의 함수인 min()max()를 사용해 a,b 중 최대값과 최소값을 판별해 각각의 변수에 담아줍니다. 그리고 그것을 비교해 연산해줍니다.

변수를 두 개나 더 생성해야 하니까 성능적으로는 더 안좋을 수도 있을 것 같습니다. 

하지만 이게 제 수준에서는 이게 최선......😂

 

 

🔍 다른 사람의 풀이

class Solution {

    public long solution(int a, int b) {
        return sumAtoB(Math.min(a, b), Math.max(b, a));
    }

    private long sumAtoB(long a, long b) {
        return (b - a + 1) * (a + b) / 2;
    }
}

 

등차수열 합 공식을 사용했다고 합니다...😲

이런 수학적 머리..갖고싶다...

등차수열의 합=2(b−a+1)×(a+b)

 


 

3️⃣ 콜라츠 추측

 

문제 설명

1937년 Collatz란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될 때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업은 다음과 같습니다.

1-1. 입력된 수가 짝수라면 2로 나눕니다. 
1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다. 
2. 결과로 나온 수에 같은 작업을 1이 될 때까지 반복합니다. 

예를 들어, 주어진 수가 6이라면 6 → 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1 이 되어 총 8번 만에 1이 됩니다. 위 작업을 몇 번이나 반복해야 하는지 반환하는 함수, solution을 완성해 주세요. 단, 주어진 수가 1인 경우에는 0을, 작업을 500번 반복할 때까지 1이 되지 않는다면 –1을 반환해 주세요.

제한사항

  • 입력된 수, num은 1 이상 8,000,000 미만인 정수입니다.

입출력 예

n return
6 8
16 4
626331 -1

 

입출력 예 #1
문제의 설명과 같습니다.

 

입출력 예 #2
16 → 8 → 4 → 2 → 1 이 되어 총 4번 만에 1이 됩니다.

 

입출력 예 #3
626331은 500번을 시도해도 1이 되지 못하므로 -1을 리턴해야 합니다.

 

 

💻 나의 풀이

class Solution {
    public int solution(int num) {
        int answer = 0;
        
        while(num != 1) {   // 1이 아닐 동안 = 1이 될 때까지 반복하겠다.
            if(num % 2 == 0)
                num /= 2;
            else
                num = num * 3 + 1;
            answer++;    // 반복 횟수 증가
            
            if(answer >= 500) {
                answer = -1;
                break;
            }
        }
        
        return answer;
    }
}

 

while(num != 1) 문으로 num이 1이 아닐 동안 (= 1이 될 때까지) 반복되도록 해줬습니다.

정해진 사이클이 끝날 때 마다 answer++를 해주어 작업을 몇 번 반복했는지 횟수를 증가시켜주고, 만약 작업이 500번 이상 반복된다면 -1을 반환해주고 멈추게끔 break를 걸어줍니다.

자, 이렇게 하면 통과..?!

 

 

가 아니고....테스트3에서 실패하고 말았습니다.

로직을 다시 봤는데도 틀린 건 없어보입니다.

문제는 테스트3에서 626331이라는 큰 값을 계산할 때 489번째에서 int의 최대치는 넘었기 때문입니다...생각도 못한 정체 ㄴㅇㄱ

 

 

class Solution {
    public int solution(long num) {
        int answer = 0;
        
        while(num != 1) {
            if(num % 2 == 0)
                num /= 2;
            else
                num = num * 3 + 1;
            answer++;    // 반복 횟수 증가
            
            if(answer >= 500) {
                answer = -1;
                break;
            }
        }
        
        return answer;
    }
}

 

매개변수를 int에서 long형으로 바꿔주니 통과됐습니다!

이런 경우의 문제도 있네요...! 😮

 

 

🔍 다른 사람의 풀이

class Collatz {
    public int collatz(int num) {
    long n = (long)num;
    for(int i=0; i<500; i++){
        if(n==1) return i; 
      n = (n%2==0) ? n/2 : n*3+1;
    }

        return -1;
    }

    // 아래는 테스트로 출력해 보기 위한 코드입니다.
    public static void main(String[] args) {
        Collatz c = new Collatz();
        int ex = 6;
        System.out.println(c.collatz(ex));
    }
}

 

삼항식...제법 친해졌다고 생각했는데 막상 코드 작성할 때는 잘 사용을 못하네요. 더욱 친해지자. ㅠㅠ

 

 

 


 

 

4️⃣ 음양 더하기

 

문제 설명

어떤 정수들이 있습니다. 이 정수들의 절댓값을 차례대로 담은 정수 배열 absolutes와 이 정수들의 부호를 차례대로 담은 불리언 배열 signs가 매개변수로 주어집니다. 실제 정수들의 합을 구하여 return 하도록 solution 함수를 완성해주세요.

제한사항

  • absolutes의 길이는 1 이상 1,000 이하입니다.
    • absolutes의 모든 수는 각각 1 이상 1,000 이하입니다.
  • signs의 길이는 absolutes의 길이와 같습니다.
    • signs[i] 가 참이면 absolutes[i] 의 실제 정수가 양수임을, 그렇지 않으면 음수임을 의미합니다.

입출력 예

absolutes signs result
[4,7,12] [true,false,true] 9
[1,2,3] [false,false,true] 0

 

입출력 예 #1

  • signs가 [true,false,true] 이므로, 실제 수들의 값은 각각 4, -7, 12입니다.
  • 따라서 세 수의 합인 9를 return 해야 합니다.

입출력 예 #2

  • signs가 [false,false,true] 이므로, 실제 수들의 값은 각각 -1, -2, 3입니다.
  • 따라서 세 수의 합인 0을 return 해야 합니다.

 

💻 나의 풀이

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        
        for(int i = 0; i < signs.length; i++) {
            if(signs[i]) {    // 양수일 경우
                answer += absolutes[i];
            } else {   // 음수일 경우
                answer -= absolutes[i];
            }
        }
        return answer;
    }
}

 

처음에 쓴 코드 입니다.

 

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        
        for(int i = 0; i < signs.length; i++) {
            answer += signs[i] ? absolutes[i] : -absolutes[i];   // 삼항식
        }
        return answer;
    }
}

 

삼항식으로 변경해봤습니다.

 

 

🔍 다른 사람의 풀이

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        for (int i=0; i<signs.length; i++)
            answer += absolutes[i] * (signs[i]? 1: -1);
        return answer;
    }
}

 

삼항식만 해도 깔끔하게 잘 썼다고 생각했는데...

이 코드를 보고 무릎을 탁 쳤습니다. 너무 깔끔하고 수행시간도 빠르네요.

 

 


 

 

 

 5️⃣ 서울에서 김서방 찾기

 

문제 설명

String형 배열 seoul의 element중 "Kim"의 위치 x를 찾아, "김서방은 x에 있다"는 String을 반환하는 함수, solution을 완성하세요. seoul에 "Kim"은 오직 한 번만 나타나며 잘못된 값이 입력되는 경우는 없습니다.

제한사항

  • seoul은 길이 1 이상, 1000 이하인 배열입니다.
  • seoul의 원소는 길이 1 이상, 20 이하인 문자열입니다.
  • "Kim"은 반드시 seoul 안에 포함되어 있습니다.

입출력 예

seoul return
["Jane", "Kim"] "김서방은 1에 있다"

 

 

💻 나의 풀이

import java.util.Arrays;

public class Solution {
    public String solution(String[] seoul){
        //x에 김서방의 위치를 저장하세요.
        int x = Arrays.asList(seoul).indexOf("Kim");  
        
        return new StringBuilder("김서방은 ").append(x).append("에 있다").toString();
        
    }
}

 

xoo | 수진