문제
두 수의 최소공배수(Least Common Multiple)란 입력된 두 수의 배수 중 공통이 되는 가장 작은 숫자를 의미합니다. 예를 들어 2와 7의 최소공배수는 14가 됩니다. 정의를 확장해서, n개의 수의 최소공배수는 n 개의 수들의 배수 중 공통이 되는 가장 작은 숫자가 됩니다. n개의 숫자를 담은 배열 arr이 입력되었을 때 이 수들의 최소공배수를 반환하는 함수, solution을 완성해 주세요.
제한 사항
- arr은 길이 1이상, 15이하인 배열입니다.
- arr의 원소는 100 이하인 자연수입니다.
입출력 예
풀이 방법
1. 내 코드
내가 생각한 방법은 주어진 배열에서 가장 큰 값을 찾고, 반복문을 돌며 나머지 배열의 값들이 가장 큰 값에 나누어 떨어져지는지 확인하는 방법이다.
현재 배열에서 가질 수 있는 가장 작은 최소공배수는 배열에서 가장 큰 값이기 때문에 max값이 초점을 잡았다.
그리고 만약 나누어 떨어지지 않는 값이 있다면 현재의 max값은 최소공배수가 될 수 없으므로 max값에 (n+1)을 해줘야한다.
1. 배열을 오름차순 정렬하고, 배열의 마지막 인덱스 값을 max라는 변수에 초기화한다.
var arrSorted = arr.sorted()
var max = arrSorted[arrSorted.size-1]
2. 배열을 돌면서 0으로 나누어 떨어지는지 확인하기 위해 cnt 변수를 만들어줬다.
while문에서 빠져나갈 수 있는 조건은 배열의 길이 - 1 (1을 뺀 이유는 max 값은 빠졌기 때문) 와 cnt 값이 같을 때이다.
반복문을 돌며 나누어 떨어지는지 확인하고 나누어 떨어진다면 cnt의 값을 증가시키고 떨어지지 않는다면 멈춤으로써
조금이라도 시간을 줄여본다.
그리고 꼭 num을 1 증가시켜줘야한다. 현재 예제에서는 max 값이 14이고 그 다음 유력한 최소공배수는 14 * 2 이기 때 문 !
var cnt = 0
var num = 1
while(cnt != arrSorted.size-1){
cnt = 0
for(i in 0 until arrSorted.size-1){
if((num * max) % arrSorted[i] == 0){
cnt++
}else{
break
}
}
num++
}
3. 마지막으로 while문을 탈출했을 때 만나는 코드다. max에 num-1을 곱해준다. 1을 빼는 이유는 위의 코드에서 마지막에 num++를 해줬기 때문이다.
answer = (num-1) * max
2. 유클리드 호제법(다른 사람 풀이)
두 개의 값을 계속 비교하면서 최소 공배수를 찾는다. 이 때 두 수 a,b의 최소 공배수는 a * b / (a,b의 최대공약수) 이다.
1. 배열의 첫번째 값을 answer에 담는다.
var answer = arr[0]
2. arr를 반복하며 최종적으로 answer에 담기는 값이 배열의 최소 공배수이다.
arr.forEach{
answer = lcm(answer, it)
}
3. a, b의 최소 공배수는 a * b / (a,b의 최대 공약수) 이다.
fun lcm(a: Int, b: Int) = a * b / gcd(a, b)
4. 최대 공약수는 a,b 중 큰 값을 작은 값으로 나눈 나머지, 작은 값을 계속 구하며 작은 값이 0이 될 때까지 반복하면 된다.
이 때 작은 값이 0이 될 때 나머지 하나 값이 최대공약수가 된다.
fun gcd(a: Int, b: Int) : Int {
return if(a < b) {
if(a == 0) b else gcd(a, b%a)
}else{
if(b == 0) a else gcd(b, a%b)
}
}
코드
1. 내 코드(시간 잡아먹는 괴물..)
class Solution {
fun solution(arr: IntArray): Int {
var answer = 0
var arrSorted = arr.sorted()
var max = arrSorted[arrSorted.size-1]
println(max)
var cnt = 0
var num = 1
while(cnt != arrSorted.size-1){
cnt = 0
for(i in 0 until arrSorted.size-1){
if((num * max) % arrSorted[i] == 0){
cnt++
}
}
// println(cnt)
num++
}
answer = (num-1) * max
return answer
}
}
2. 유클리드 호제법 사용
class Solution {
fun solution(arr: IntArray): Int {
var answer = arr[0]
arr.forEach{
answer = lcm(answer, it)
}
return answer
}
fun lcm(a: Int, b: Int) = a * b / gcd(a, b)
fun gcd(a: Int, b: Int) : Int {
return if(a < b) {
if(a == 0) b else gcd(a, b%a)
}else{
if(b == 0) a else gcd(b, a%b)
}
}
}
느낀점
기존 내 풀이랑 유클리드 호제법으로 풀었을 때의 시간 차이가 어마무시하다 ...
앞으로 꼭 기억해야지 ..
'Algorithm > kotlin' 카테고리의 다른 글
[프로그래머스/Kotlin] 체육복 (Lv. 1) (0) | 2024.04.03 |
---|---|
[프로그래머스/Kotlin] 덧칠하기 (Lv. 1) (0) | 2024.04.03 |
[프로그래머스/Kotlin] 공원 산책 (Lv. 1) (2) | 2024.03.29 |
[프로그래머스/Kotlin] 이진 변환 반복하기 (Lv. 2) (0) | 2024.03.27 |
[프로그래머스/Kotlin] JadenCase 문자열 만들기 (Lv. 2) (0) | 2024.03.27 |