
이 문제는 주어진 숫자의 2진수에서 1의 개수가 같은 다음 숫자를 찾는 문제. 이를 해결하기 위해서는 먼저 n의 2진수에서 1의 개수를 구한 뒤, 그 다음 숫자들 중에서 1의 개수가 같은 숫자를 찾으면 된다.
먼저 n을 2진수로 변환하여 1의 개수를 셈.
n보다 큰 숫자를 하나씩 증가시키면서 2진수로 변환 후 1의 개수가 같은지 확인.
조건을 만족하는 가장 작은 숫자를 찾으면 그 값을 반환.
function solution(n) {
// n의 2진수에서 1의 개수
const countOnes = (num) => num.toString(2).split('1').length - 1;
const targetCount = countOnes(n);
let nextNum = n + 1;
// 다음 숫자의 1의 개수가 n과 같을 때까지 반복
while (countOnes(nextNum) !== targetCount) {
nextNum++;
}
return nextNum;
}
countOnes 함수:
숫자를 2진수 문자열로 변환 (num.toString(2)).
'1'을 기준으로 문자열을 나누고 (split('1')), 배열의 길이를 구해.
1의 개수는 배열의 길이에서 1을 뺀 값 (length - 1).
왜 1을 빼냐고?
우리가 숫자를 2진수로 변환한 후 1의 개수를 세기 위해, split('1')이라는 메서드를 사용하고 있다. 그런데 split('1')은 1을 기준으로 문자열을 쪼개서 배열을 만들어줌. 이 과정에서 1이 등장하는 자리를 기준으로 분할되기 때문에, 배열의 길이가 1의 개수보다 항상 1개 더 많아짐.
다시 정리하면
split('1')은 1을 기준으로 문자열을 나누어 배열을 만드는데, 그 배열의 길이는 실제 1의 개수보다 1개 더 많다.
따라서 정확한 1의 개수를 얻기 위해서는 배열의 길이에서 1을 빼야 함.
이 과정을 통해 정확한 1의 개수를 구할 수 있습니다. 그래서 length - 1을 사용한 것!
메인 함수 solution:
먼저, 주어진 n의 1의 개수를 targetCount에 저장.
n보다 큰 수부터 하나씩 확인하기 위해 nextNum을 n + 1로 설정.
while 루프를 사용해 nextNum의 1의 개수가 targetCount와 같을 때까지 nextNum을 증가.
조건을 만족하는 수를 찾으면 그 수를 반환.
더 쉽게 설명하면
2진수 변환과 1 세기:
숫자를 컴퓨터가 이해하는 2진수로 바꾸고, 그 안에 1이 몇 개 있는지 세는 것.
조건에 맞는 수 찾기:
주어진 숫보다 큰 수부터 하나씩 올라가면서, 그 수의 2진수 1 개수가 원래 숫과 같은지 확인.
같은 개수를 찾으면 그 수가 우리가 원하는 "다음 큰 숫자".
왜 이렇게 할까?:
가장 먼저 조건을 만족하는 수가 가장 작은 수이기 때문에, 이 방법으로 효율적으로 찾을 수 있겠다!
지난번에 다짐했을 때는 3단계 문제를 풀고 나서 글을 작성하려고 했는데, 오늘은 바빠서 급하게 후다닥 풀고 바로 작성하고 있다. 그런데 "아는 만큼 보인다"는 말이 정말 맞는 것 같다. 요즘 Udemy에서 인강을 보고 있는데, 섹션 1이 JavaScript에 대한 내용이었다. 지금 문제를 풀면서 split 같은 걸 써보니, 확실히 인강에서 배운 게 실제로 적용되면서 학습 효과가 극대화되는 느낌이다!

핳 간다!
12시에 티케팅 광클을 하고, 내가 간다. 살면서 첫 티켓팅,,
콜드플레이면 대만족