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();
}
}
'프로그래머스 > 1단계' 카테고리의 다른 글
3진법 뒤집기 / 예산 / 이상한 문자 만들기 / 크기가 작은 부분문자열 / 삼총사 (1) | 2024.01.24 |
---|---|
문자열 다루기 기본 / 행렬의 덧셈 / 직사각형 별찍기 / 최대공약수와 최소공배수 / 같은 숫자는 싫어 (0) | 2024.01.22 |
가운데 글자 가져오기 / 수박수박수박수박수박수? / 약수의 개수와 덧셈 / 문자열 내림차순으로 배치하기 / 부족한 금액 계산하기 (0) | 2024.01.20 |
나누어 떨어지는 숫자 배열 / 없는 숫자 더하기 / 핸드폰 번호 가리기 / 제일 작은 수 제거하기 / 내적 (1) | 2024.01.15 |
자릿수 더하기 / 문자열 내 p와 y의 개수 / 자연수 뒤집어 배열로 만들기 / 정수 제곱근 판별 / 정수 내림차순으로 배치하기 (1) | 2024.01.08 |