[Programmers] 2개 이하로 다른 비트

2023. 9. 12. 20:03Computer Sciences/Problem Solve

https://school.programmers.co.kr/learn/courses/30/lessons/77885

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 설명

비트 처리에 관한 문제이다. 처음엔 XOR 연산을 통해 한 비트를 이동시키면서 계산하는 방식으로 풀었다. 그런데 10번, 11번 TC에서 시간 초과가 발생했다. 그래서 다른 방법을 찾던 중 규칙을 통해 해결하는 방법을 알게 되었고 이를 활용해 해결했다.

 

먼저 짝수는 매우 간단히 해결할 수 있다. 이진수 특성상 짝수의 첫 번째 비트는 항상 0이기 때문에 1을 더하기만 하면 된다.

홀수의 경우에는 처음 0이 나올 때까지 계속 2로 나누어준다. 그러다 나머지가 0인 경우, 즉 0을 발견하면 01을 10으로 바꾸어주면 2비트가 다른 최솟값이 나오게 된다. 이는 곧 0이 나타나기 이전의 마지막 1비트에 해당하는 수를 더해주는 것과 같다. 예를 들어 5의 경우 이진수로 하면 101이다. 0이 2번째에 나타났으므로 그 이전 1비트에 해당하는 수는 1이다. 따라서 101 + 1을 하면 110, 6이라는 결과가 나온다. 7의 경우 0111이다. 0이 4번째에 나타났으므로 그 이전 1비트에 해당하는 수는 100(4)이다. 이를 더하면 111 + 100 = 1011, 즉 11이라는 값이 나온다.

코드

class Solution {
    public long[] solution(long[] numbers) {
        long[] answer = new long[numbers.length];
        
        for (int i = 0; i < numbers.length; i++) {
            long num = numbers[i];
            
            if (num % 2 == 0) {
                answer[i] = num + 1;
                continue;
            }
            
            long next = num;
            int count = 0;
            while (next % 2 == 1) {
                count++;
                next /= 2;
            }
            
            answer[i] = (long)(num + Math.pow(2, count - 1));
        }
        
        return answer;
    }
}

처음 코드

class Solution {
    public long[] solution(long[] numbers) {
        long[] answer = new long[numbers.length];
        
        for (int i = 0; i < numbers.length; i++) {
            long num = numbers[i];
            long next = num + 1;
            long min = Long.MAX_VALUE;
            
            while (true) {
                long result = num ^ next;
                long count = 0L;
                
                while (result != 0) {
                    count += result & 1;
                    result = result >> 1;
                }
                
                min = Math.min(min, count);
                
                if (min <= 2) {
                    answer[i] = next;
                    break;
                }
                
                next++;
            }
        }
        
        return answer;
    }
}