출처: https://school.programmers.co.kr/learn/courses/30/lessons/77885
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제
문제 설명
양의 정수 x에 대한 함수 f(x)를 다음과 같이 정의합니다.
- x보다 크고 x와 비트가 1~2개 다른 수들 중에서 제일 작은 수
예를 들어,
- f(2) = 3 입니다. 다음 표와 같이 2보다 큰 수들 중에서 비트가 다른 지점이 2개 이하이면서 제일 작은 수가 3이기 때문입니다.

- f(7) = 11 입니다. 다음 표와 같이 7보다 큰 수들 중에서 비트가 다른 지점이 2개 이하이면서 제일 작은 수가 11이기 때문입니다.
정수들이 담긴 배열 numbers가 매개변수로 주어집니다. numbers의 모든 수들에 대하여 각 수의 f 값을 배열에 차례대로 담아 return 하도록 solution 함수를 완성해주세요.
제한사항
- 1 ≤ numbers의 길이 ≤ 100,000
- 0 ≤ numbers의 모든 수 ≤ 1015
입출력 예
풀이
참고로 저는 비트 시프트 연산자를 잘 사용하지 못해서 비트 연산자를 사용하지 않는 방법으로 풀었습니다..!
제가 생각했을 때 베스트 풀이 방법은 아닌 듯해서 이런 풀이 방법도 있구나 하고 참고용으로만 봐주시면 좋을 것 같습니다.
구해야 할 것은 "x보다 크고 x와 비트가 1~2개 다른 수들 중에서 제일 작은 수" 인데 이 수에는 규칙이 있습니다.
(고수님 덕분에 팁을 알게 되었습니다.)
x를 2진수로 변환했을 때, 뒤에서부터 가장 먼저 나오는 0을 1로 바꾸고 그 0의 오른쪽에 있는 1을 0으로 바꾸면 됩니다.
x보다 큰 수여야 하니까 0을 1로 변환해야하고, 비트가 1~2개 다르면서 그 중 제일 작은 수여야 하니까 바로 오른쪽에 있는 1을 0으로 바꿔주는 것입니다.
여러 1이 있겠지만 여러 개를 0으로 바꿔주면 비트가 3개 이상 달라지게 되기 때문에 1개만 바꿔줍니다. 또 그 중 제일 작아야 하기 때문에 가장 높은 자리인 0의 오른쪽 자리의 1을 0으로 바꿔줍니다. 만약 더 오른쪽에 있는 1을 바꿔준다면 그 수는 제일 작은 수가 아니니까요!
이 규칙은 조건이 있는데 0이 하나 이상 포함돼야 하고, 뒤에서 가장 먼저 나오는 0의 오른쪽에 1이 하나라도 있어야 합니다.
그래서 3가지의 조건을 나눠서 코드를 작성했습니다.
- 0으로 끝나는 수일 때 => 0을 1로 바꿔줍니다.
- ex) 110(6) -> 111(7)
- 0이 중간에 포함되어 있을 때 => 뒤에서부터 가장 먼저 나오는 0을 1로 바꾸고 오른쪽에 있는 1을 0으로 바꿉니다.
- ex) 1001(9) -> 1010(10)
- 중간에 0이 포함되어 있지 않고 1로만 이루어져 있을 때 => 첫번째 1을 0으로 바꾸고 앞에 1을 붙여줍니다.
- ex) 1111(15) -> 10111(23)
이렇게 구하고자 하는 수를 구하고 10진수로 변환해주면 됩니다.
소스코드
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];
String biNumber = Long.toBinaryString(number);
String biFNum = "";
boolean noZero = true;
for(int j=biNumber.length() - 1; j>=0; j--){
if(biNumber.charAt(j) == '0'){
noZero = false;
// 0으로 끝날 때
if(j == biNumber.length() - 1){
biFNum = biNumber.substring(0, j) + "1";
}
// 중간에 0이 있을 때
else{
biFNum = biNumber.substring(0, j) + "10" + biNumber.substring(j+2, biNumber.length());
}
break;
}
}
// 1만 있을 때
if(noZero){
biFNum = "10" + biNumber.substring(1, biNumber.length());
}
long fNum = Long.parseLong(biFNum, 2);
answer[i] = fNum;
}
return answer;
}
}
'Programming > Programmers' 카테고리의 다른 글
[프로그래머스] Lv2. 롤케이크 자르기 (Java) (0) | 2023.07.05 |
---|---|
[프로그래머스] Lv2. 2 x n 타일링 (Java) (0) | 2023.07.04 |
[프로그래머스] Lv 1. 개인정보 수집 유효기간 (Java) (0) | 2023.07.03 |
[프로그래머스] Lv 1. 공원 산책 (Java) (0) | 2023.07.02 |
[프로그래머스] Lv 1. 달리기 경주 (Java) (0) | 2023.07.02 |