TIL_250331

듀듀·2025년 3월 31일

spring_TIL

목록 보기
31/53

2개 이하로 다른 비트

링크텍스트

시행 착오 및 풀이 방법

틀린 풀이 방법

  1. 이진수로 변환 후 while동안 +1을 하며 각 인덱스에서 다른 부분을 찾아서 diff++해준다.
  2. 전체 길이가 다를 수 있으므로 둘 중 긴 길이에 맞춰서 0을 추가해준다.
  3. diff가 2보다 작으면 break
    3-1. for문 바깥에서 diff가 2보다 작은지 확인해야 한다. 그렇지 않으면 diff가 늘어날 때 무조건 2보다 작기때문에 바로 뒷 숫자가 들어가버린다.

for문 안에 while문 있고 그 안에 또 for문이 있어서.. 시간 초과가 뜰 것이라 예상했었다.
예상적중

오답 코드

import java.util.*;
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];
            String bn = Long.toBinaryString(num);
            
            while (true) {
                num++; 
                String bn_next = Long.toBinaryString(num);
                
                int diff = 0;
                int len1 = bn.length();
                int len2 = bn_next.length();
                int maxLen = Math.max(len1, len2);
                
                for (int j = 0; j < maxLen; j++) {
                    char ch_prev;
                    char ch_next;
                    
                    //전체 길이가 안맞을 경우에는 앞에 0을 채우기
                    //bn의 앞쪽을 0으로 채우기
                    if (j < maxLen - len1) {
                        ch_prev = '0';
                    } else {
                        ch_prev = bn.charAt(j - (maxLen - len1));
                    }
                    
                    //bn_next의 앞쪽을 0으로 채우기
                    if (j < maxLen - len2) {
                        ch_next = '0';
                    } else {
                        ch_next = bn_next.charAt(j - (maxLen - len2));
                    }
                    
                    if (ch_prev != ch_next) {
                        diff++;
                    }
                    
                    if (diff > 2) {
                        break;
                    }
                }

                if (diff <= 2) {
                    answer[i] = num;
                    break;
                }
            }
        }
        
        return answer;
    }
}

떼잉.. 다른 방법이 안떠오르는데... 결국 예전에 푼 정답을 참고하였슴다^^

맞는 풀이 방법

  1. 짝수일 경우 맨 뒷자리는 무조건 0, 그러므로 +1만 해주면 됨
  2. 홀수일 경우 뒤에서 0이 시작되는 인덱스를 10으로 바꿔주면 됨
  3. 홀수인데 0이 없는 경우는 맨 앞에 10을 붙여주면됨
    이런식으로 하면 비트가 다른 지점이 2개 이하이면서 가장 작은 수 완성

이런 방법이!!!! 깜짝 놀랬소다

정답 코드

/*
1. 짝수일 경우 맨 뒷자리는 무조건 0, 그러므로 +1만 해주면 됨
2. 홀수일 경우 뒤에서 0이 시작되는 인덱스를 10으로 바꿔주면 됨
3. 홀수인데 0이 없는 경우는 맨 앞에 10을 붙여주면됨
이런식으로 하면 비트가 다른 지점이 2개 이하이면서 가장 작은 수 완성
*/
import java.util.*;
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];
            
            //짝수라면 +1
            if(num % 2 == 0) {
                answer[i] = num+1;
            }
            //홀수라면
            else {
                //2진수로 변환
                String str = Long.toString(num, 2);
                
                //0의 인덱스 확인
                int idx = str.lastIndexOf("0");
                
                //0이 있는 홀수라면
                if(idx != -1) {
                    str = str.substring(0, idx) + "10" + str.substring(idx+2);
                }
                //0이 없는(1로만 채워진) 홀수라면
                else {
                    str = "10" + str.substring(1);
                }
                
                answer[i] = Long.parseLong(str,2);
            }
        }
        return answer;
    }
}

문법 정리

마지막 인덱스 위치 확인

str.lastIndexOf("0")

없다면 -1을 반환한다.


2진수 String -> Long 변환

Long.parseLong(str,2)

도대체 머리가 얼마나 비상해야 저런 풀이 방법이 촥촥 떠오를까
아직도 멀었다는 것을 실감한다 흑흑슨

0개의 댓글