일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 빅데이터분석기사
- 가운데 글자 가져오기 파이썬
- 빅분기실기
- 가운데 글자 가져오기 python
- 프로그래머스 가운데 글자 가져오기 파이썬
- m1 docker
- 프로그래머스 나누어 떨어지는 숫자 배열 파이썬
- 프로그래머스 가운데 글자 가져오기 python
- 최단 경로 알고리즘
- 코드업 1020 자바
- 나누어 떨어지는 숫자 배열 python
- 트리의 지름 java
- docker 삭제
- docker 완전 삭제
- 최소 스패닝 트리 자바
- docker remove
- 프로그래머스 가운데 글자 가져오기 자바
- 청년 AI Big Data 아카데미 13기
- 나누어 떨어지는 숫자 배열 java
- 핸즈온 머신러닝
- 프로그래머스 나누어 떨어지는 숫자 배열 자바
- 코드업 1020 java
- 청년 Ai Big Data 아카데미
- 트리의 지름 자바
- codeup 1020 자바
- 가운데 글자 가져오기 java
- 최소 스패닝 트리
- codeup 1020 java
- 가운데 글자 가져오기 자바
- m1 docker install
- Today
- Total
NineTwo meet you
[프로그래머스/자바] 2개 이하로 다른 비트 본문
문제 설명
양의 정수 x에 대한 함수 f(x)를 다음과 같이 정의합니다.
- x보다 크고 x와 비트가 1~2개 다른 수들 중에서 제일 작은 수
예를 들어,
- f(2) = 3 입니다. 다음 표와 같이 2보다 큰 수들 중에서 비트가 다른 지점이 2개 이하이면서 제일 작은 수가 3이기 때문입니다.
수 | 비트 | 다른 비트의 개수 |
3 | 000...0011 | 1 |
2 | 000...0010 |
- f(7) = 11 입니다. 다음 표와 같이 7보다 큰 수들 중에서 비트가 다른 지점이 2개 이하이면서 제일 작은 수가 11이기 때문입니다.
수 | 비트 | 다른 비트의 개수 |
7 | 000...0111 | |
8 | 000...1000 | 4 |
9 | 000...1001 | 3 |
10 | 000...1010 | 3 |
11 | 000...1011 | 2 |
정수들이 담긴 배열 numbers가 매개변수로 주어집니다. numbers의 모든 수들에 대하여 각 수의 f 값을 배열에 차례대로 담아 return 하도록 solution 함수를 완성해주세요.
제한사항
- 1 ≤ numbers의 길이 ≤ 100,000
- 0 ≤ numbers의 모든 수 ≤ 1015
입출력 예
numbers | result |
[2,7] | [3,11] |
입출력 예 설명
입출력 예 #1
- 문제 예시와 같습니다.
설명
간단하게 생각해서 입력받는 numbers부터 큰수를 다 살펴보고 XOR연산을 통해 그 값의 bitCount가 1또는 2인경우 답으로 살펴보았더니 시간초과가 발생했다.
따라서 숫자를 다 살펴보는 것은 안된다.
다르게 문제를 해결해야 하는데 문제에 힌트가 있다.
x보다 크고 x와 비트가 1~2개 다른 수들 중에서 제일 작은 수
그러면 언제 비트가 1개 클때 제일 작은 수가 되고
2개 클때 제일 작은 수가 되는 것은 무엇일까?
바로 짝수와 홀수다.
1) 짝수인 경우,
n = 2 => 10
n= 4 => 100
n = 6 => 110
n = 8 => 1000
:
이런식으로 2진수로 변환하게 되는데 잘 생각해보면 끝자리가 모두 0인 것을 알 수 있다.
따라서 끝자리를 1로 바꾸면 비트가 1개 바뀌고 x보다 크면서 제일 작은 수가 된다.
이말을 다른 말로 하면 짝수인 경우 = 값 + 1 하면 된다는 말고 같다.
2) 홀수인 경우,
n = 3 => 11 ==> 101
n = 5 => 101 ==> 110
n = 7 => 111 ==> 1011
n = 9 = > 1001 ==> 1010
n = 11 => 1011 ==> 1101
n = 13 => 1101 ==> 1110
n = 15 => 1111 ==> 10111
:
이런식으로 2진수로 변환하게 된다.
이때 홀수가 두가지 경우로 나뉘게 되는데 모두1만 있는 수와 1과 0이 섞인수이다.
2-1) 모두 1비트만 있는경우
비트 1값을 바꾸면 값이 x보다 작아진다.
따라서 맨앞 비트를 0으로 바꾸는 대신 더 앞에 1비트를 추가해야 한다.
2-2) 0비트가 포함된경우
해당 값만 1비트로 바꾸면 물론 x보다는 커지지만 이값은 제일 작은 값이 되지 않는다.
따라서 가장 먼저 나오는 0비트를 1로 바꾸는 대신 그 뒤에 있는 비트가 0으로 바뀌면 2개의 비트가 바뀌지만 제일 작은 값이 된다.
코드
'프로그래밍 문제 > 프로그래머스' 카테고리의 다른 글
[프로그래머스/자바] 위클리 챌린지 2주차 상호 평가 (0) | 2021.08.10 |
---|---|
[프로그래머스/자바] 거리두기 확인하기 (0) | 2021.08.06 |
[프로그래머스/자바] 숫자 문자열과 영단어 (0) | 2021.08.05 |
[프로그래머스/자바] 부족한 금액 계산하기 (0) | 2021.08.05 |
[프로그래머스/자바] 2017 카카오코드 본선 리틀 프렌즈 사천성 (0) | 2021.06.21 |