코딩 테스트 및 알고리즘/leetcode for google
leetcode medium : Minimize XOR
띠리링구
2022. 10. 3. 15:37
https://leetcode.com/problems/minimize-xor/
굉장히 까다로웠다.
일단 num2에 1이 몇 개 있는지를 세는 것부터 시작한다.
그리고 num1의 큰 자릿수 부터 1을 채워가며 x를 찾는다. 그래야 xor할때 제일 작아지니까.
문제는 num1과 num2의 1의 개수가 다른 경우인데
이거때문에 두 숫자의 1 개수의 mininum을 구해서 그만큼 앞에서부터 채우고
num2가 1이 더 많아서 남는 경우엔 뒤에서부터 채우는 방법을 썼다.
class Solution:
def minimizeXor(self, num1: int, num2: int) -> int:
def count(num):
if num == 0: return 0
return num % 2 + count(num//2)
numOfSetBits = count(num2)
lst = []
i = 0
tmp = num1
while tmp:
if tmp % 2:
lst.append(i)
tmp //= 2
i += 1
x = 0
for i in range(1, min(len(lst), numOfSetBits) + 1):
x += 2**lst[-i]
p = 0
for i in range(numOfSetBits-len(lst)):
while 2**p & num1 != 0:
p += 1
x += 2**p
p += 1
return x
코드는 굉장히 지저분쓰 하지만
성능은 나쁘지 않게 나왔다.
근데 discussion 들어가보고 깜짝 놀라고 말았다.
class Solution:
def minimizeXor(self, num1: int, num2: int) -> int:
a, b = num1.bit_count(), num2.bit_count()
res = num1
for i in range(32):
if a > b and (1 << i) & num1 > 0:
res ^= 1 << i
a -= 1
if a < b and (1 << i) & num1 == 0:
res ^= 1 << i
a += 1
return res
일단 int클래스에 bit_count 메서드라는게 있는것부터 처음 알았다.
이분은 result를 num1으로 먼저 초기화해놓고 num1의 1의개수(a)와 num2의 1의개수(b)를 비교해서 num1이 더 많으면 그만큼 작은 자리수에서부터 1을 빼고 (앞에서부터 채우는게 아니라 뒤에서 빼는걸로.. 반대로 하셨다.) num2가 더 많으면 1을 채워나가는걸로 하셨다. 근데 이게 두 숫자의 1의 개수를 비교해가면서 원스캔으로 할 수 있는건지는 전혀 몰랐다. 대단하다..