[Java] 12911 다음 큰 숫자
1. 문제
다음 큰 숫자
2. 정답코드
비트 조작으로 쉽게 풀 수 있는 문제이다. Integer.bitCount() 메서드를 쓰면 2진수에서 1의 개수를 쉽게 셀 수 있다.
class Solution {
public int solution(int n) {
int count = Integer.bitCount(n); // n의 1 개수
int next = n + 1;
while (Integer.bitCount(next) != count) {
next++;
}
return next;
}
}
- 먼저 Integer.bitCount(n) 으로 n의 1의 개수를 구한다.
- n보다 큰 수부터 하나씩 증가시키면서 bitCount를 비교한다.
- 동일한 개수를 가지는 수를 만나면 그게 바로 답이다.
이 방식은 단순하면서도 제한 사항(최대 백만)에서도 충분히 돌아간다.
다읃 큰 수(next higher number with same number of 1-bits) 알고리즘
class Solution {
public int solution(int n) {
int c = n;
int c0 = 0; // 끝의 0 개수
int c1 = 0; // 끝의 1 개수
// 1. n의 마지막 연속된 0 개수 세기
while ((c & 1) == 0 && c != 0) {
c0++;
c >>= 1;
}
// 2. 그 뒤에 연속된 1 개수 세기
while ((c & 1) == 1) {
c1++;
c >>= 1;
}
// n이 111...000 같은 형태면 더 큰 수 없음 (문제 조건에선 1,000,000 이하라 항상 있음)
if (c0 + c1 == 31 || c0 + c1 == 0) {
return -1;
}
// 3. 0 → 1로 바꿀 위치 찾기
int p = c0 + c1;
// 4. 해당 비트를 1로 변경
n |= (1 << p);
// 5. 그 오른쪽 비트는 모두 0으로 초기화
n &= ~((1 << p) - 1);
// 6. 오른쪽에 (c1-1)개의 1을 채워 넣기
n |= (1 << (c1 - 1)) - 1;
return n;
}
}
작동 원리
예를 들어 n = 78 (1001110)일 때:
- 끝에서 연속된 0 개수(c0) = 1
(...10 → 끝의 0 하나) - 2. 그 앞에서 연속된 1 개수(c1) = 3
(...1110 → 111) - p = c0 + c1 = 4
즉, 오른쪽에서 4번째 비트를 0→1로 바꿔야 함. - 그 뒤의 비트들을 0으로 초기화한 뒤,
- 가장 작은 수를 만들기 위해 맨 오른쪽에 (c1-1)개의 1을 배치한다.
결과: 1010011 (83)