
오늘은 코드 카타를 풀고, 과제를 진행했습니다.
정말 이 두 가지에 대부분의 시간을 썼습니다.
바로 시작하겠습니다.
[ 09:00 ~ 10:00, 11:00 ~ 12:00 ]
오늘의 코드 카타는 타겟 넘버 입니다.
어제 했던 것처럼 알고리즘에 대한 지식이 있어야만 풀 수 있지만,
저는 알고리즘을 잘 모르기 때문에 직접 풀었습니다.
당연히 알고리즘을 사용하는 게 시간복잡도도 잘 나오니, 알고리즘을 공부해야 할 것 같습니다.
일단 문제입니다.
n개의 음이 아닌 정수들이 있습니다. 이 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.
-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3
사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.
어제 문제처럼 전부 돌아보는 게 맞는 거 같아서 이번에도 그렇게 알고리즘을 짜보자고 생각했습니다.
결국, 연산하는 건 +, - 이 두 가지 경우의 수이고, 모든 수에 대해 경우의 수를 전부 적용시키면 될 것 같았습니다.
물론, 이걸 코드로 짜는 부분이 문제였습니다.
반쯤 포기하고, 생각하던 중 0, 1을 보고 2진수가 떠올랐습니다. 상태는 어쨌든 2개밖에 없고, 이걸 잘 쓰면 쉽게 풀리겠다고 생각했습니다.
만약 n개의 숫자를 준다고 하면, 연산 가능한 경우의 수는 총 2^n 개 입니다.
즉, 2^n번만 돌려주면 된다는 뜻이 됩니다.
그 다음으로, 매번, 지금까지 반복한 횟수를 2진수로 바꿔줘야 합니다.
그리고, 2진수를 뒤집어준 뒤, 2진수에서 1에 해당하는 부분을 골라서 빼주었습니다.
다음은 그 코드입니다.
import kotlin.math.pow
class Solution {
fun solution(numbers: IntArray, target: Int): Int {
var answer = 0
var res = 0
var count = 0
val maxCount = (2.0).pow(numbers.size).toInt()
while(count < maxCount) {
res = 0
val binaryCount = Integer.toBinaryString(count).reversed()
for(i in numbers) {
res += i
}
for(j in 0 until binaryCount.length) {
if(binaryCount[j] == '1') res -= (numbers[j] * 2)
}
if(res == target) answer++
count++
}
return answer
}
}
0이면 그대로 다 더하고, 1이면, 0001을 뒤집은 1000을 받아들여서,
첫 번째 인덱스가 1이 되기 때문에 다 더한 값에 첫 번째 x 2 한 값을 빼주게 됩니다.
이렇게 해서 크기 n에 따라 2의 n승번만큼 진행해서 타겟 넘버와 같은 값이 몇 개인지 세줍니다.
그러고 나서 원래 풀이 방법으로 쓰이는 DFS 방법의 풀이를 써봤는데 확실히 엄청 빠르더라고요.
알고리즘을 아는 게 중요하다고 생각이 들었습니다.
오늘은 HomeActivity의 버튼을 커스텀했습니다.
잘 만든 것 같습니다.
아직 코드가 제대로 정리가 안 돼서 코드 정리 후 코드를 공개하겠습니다.
그리고 디자인도 바꿔야 할 것 같습니다.
아래 버튼처럼 조금만 추가해줘도 되게 이쁘네요.
혹시 코드가 궁금하면... 깃허브 는 여기 있습니다.
오늘은 열심히 코드 카타와 과제를 진행했습니다.
내일도 과제 하면서 시간을 보낼 것 같습니다.
디자인이 재밌는 것 같으니까 이쪽도 공부해보고 싶습니다.
예전에는 앱 개발이 그렇게 재밌진 않았는데, 요즘은 좀 재밌는 것 같습니다.
끝.