문제
십진수가 주어지고 해당 수보다 큰 수 중에서 2진수로 변환했을 때, 해당 수와 해당 수보다 큰 수의 비트 차이가 2개 이하인 수들 중 가장 작은 수를 구하라.
로직
이 문제는 3가지를 고려해주면 된다.
1. 해당 수가 4로 나눴을 때 3이 아닌가?
-> 이런 경우는 1을 더해주면 문제 조건에 맞는 수를 찾을 수 있다.
2. 모두 1인가?
-> 예를 들어, 11111 이 있다고 가정하자.
-> 해당 수에 1을 더하면 100000이 될 것이다.
-> 이 때, 가장 앞자리 10은 고정하고 나머지를 맞추는게 가장 최소이면서 2개 이하 차이나는 수이다. 101111
-> 로직 : 0을 포함하는지 확인 - 10을 앞자리로 설정 - 나머지는 길이에 맞추어 1로 채움
3. 모두 1은 아닌가?
-> 예를 들어, 100111과 같은 경우를 의미한다.
-> 예시들을 통해 알 수 있듯이 111과 같이 연속된 1이 있다면 바로 다음수가 가장 작으면서 차이가 2개이하인 수가 해당 수에 1을 더한 값이 아니게 된다.
-> 이러한 경우에는 10(10)11 으로 변경하면 된다. 즉, 원리는 괄호안에 부분만 다르고 모든 부분이 같게 설정하면 가장 작으면서 차이가 2개이하인 수를 찾을 수 있다.
-> 로직 : 0을 포함 안하는지 확인 - 0의 마지막 인덱스를 구한다. - 그 인덱스를 기준으로 앞은 그대로 하고 10 추가 나머지 추가 순으로 한다.
코드
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 number = numbers[i];
if(number % 4 != 3){
answer[i] = number+1;
}
else{
String value = Long.toBinaryString(number);
String new_value = "";
if(!value.contains("0")){
new_value += "1" + "0";
new_value += value.substring(1);
}
else{
int x = value.lastIndexOf("0");
new_value += value.substring(0, x) + "10";
new_value += value.substring(x+2);
}
answer[i] = Long.parseLong(new_value, 2);
}
}
return answer;
}
}
'Algorithm > Practice' 카테고리의 다른 글
Programmers - 스티커 모으기 with JAVA (0) | 2023.06.21 |
---|---|
Programmers - 메뉴 리뉴얼 with JAVA (0) | 2023.06.21 |
Programmers - 뒤에 있는 큰 수 찾기 with JAVA (V) (0) | 2023.06.14 |
Programmers - 숫자 짝궁 with JAVA (0) | 2023.06.13 |
Programmers - 게임 맵 최단 거리 with JAVA (V) (0) | 2023.06.12 |