更多 leetcode 题解可参考:【Programming】
1689. 十-二进制数的最少数目
如果一个十进制数字不含任何前导零,且每一位上的数字不是 0 就是 1 ,那么该数字就是一个 十-二进制数 。例如,101 和 1100 都是 十-二进制数,而 112 和 3001 不是。
给你一个表示十进制整数的字符串 n ,返回和为 n 的 十-二进制数 的最少数目。
示例 1:
输入:n = “32”
输出:3
解释:10 + 11 + 11 = 32
示例 2:
输入:n = “82734”
输出:8
示例 3:
输入:n = “27346209830709182346”
输出:9
脑筋急转弯题,题意是,给一个数,最少用多少个“由 01 组合成的数字"加起来能得到
思路:相当于把数字每个位置每次减 1,最少减多少次能使每位全成 000000000000,解法呼之欲出,给出的数字每个位置上最大的数就是答案
class Solution(object):
def minPartitions(self, n):
"""
:type n: str
:rtype: int
"""
return int(max(n))
哈哈,一行搞定,巧妙的利用了字符串排序( ASCII 码)的特性
67. 二进制求和
法一:二进制转十进制,然后相加,再转回二进制
class Solution(object):
def addBinary(self, a, b):
"""
:type a: str
:type b: str
:rtype: str
"""
return bin(int(a, 2) + int(b, 2))[2:] # 切片是为了去掉二进制的前缀
法二:加法运算,逢二进一
class Solution(object):
def addBinary(self, a, b):
"""
:type a: str
:type b: str
:rtype: str
"""
res = 0 # 记录进位
len_a = len(a)
len_b = len(b)
# 补零待加数等长
if len_a > len_b:
b = "0" * (len_a - len_b) + b
if len_b > len_a:
a = "0" * (len_b - len_a) + a
# 逆序相加
for i in range(len(a)-1, -1, -1):
add_sum = int(a[i]) + int(b[i]) + res
# 逢二进一
if add_sum > 1:
add_sum -= 2
res = 1
else:
res = 0
a = a[:i] + str(add_sum) + a[i+1:] # 字符串不支持索引替换,那就切片
# 最高位相加可能会多出一位,补上
if res == 1:
a = "1" + a
return a
相似题型
504. 七进制数(进制转换)
给定一个整数,将其转化为7进制,并以字符串形式输出。
-
示例 1:
输入: 100
输出: “202”
示例 2: -
输入: -7
输出: “-10” -
注意: 输入范围是 [-1e7, 1e7] 。
class Solution(object):
def convertToBase7(self, num):
"""
:type num: int
:rtype: str
"""
nums = abs(num)
s = ''
# 这里只对大于0的数算 7 进制
while (nums):
a = nums % 7
nums = nums // 7
s = s+ str(a)
if num > 0:
return s[::-1] # 倒序输出计算结果
elif num < 0:
return '-'+s[::-1] # 负数添加一个负号
else:
return '0' # 0 的话直接返回 0
461. 汉明距离(进制转换 / 异或)
两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。
给出两个整数 x 和 y,计算它们之间的汉明距离。
注意:
0 ≤ x, y < 231.
- 示例:
输入: x = 1, y = 4
输出: 2
解释:
1 (0 0 0 1)
4 (0 1 0 0)
↑ ↑
上面的箭头指出了对应二进制位不同的位置。
思路,计算二进制,然后比不同的位置
class Solution(object):
def hammingDistance(self, x, y):
"""
:type x: int
:type y: int
:rtype: int
"""
# 计算二进制逆序(方便后面的高位补0),结果存在列表中,
def bin_num(x):
list1 = []
while(x):
list1.append(x%2)
x = x//2
return list1
bin_x = bin_num(x)
bin_y = bin_num(y)
len_x = len(bin_x)
len_y = len(bin_y)
# 把两个二进制的长度补成一样的
if len_x < len_y:
bin_x.extend([0]*(len_y-len_x))
else:
bin_y.extend([0]*(len_x-len_y))
# 统计不一样的个数
num = 0
for i in range(len(bin_x)):
if bin_x[i]!=bin_y[i]:
num+=1
return num
还有一种比较快的方法是直接计算异或(相同为1,不同为0)
class Solution(object):
def hammingDistance(self, x, y):
"""
:type x: int
:type y: int
:rtype: int
"""
return bin(x^y).count('1')
补充,异或运算的性质
- a ⊕ a = 0
- a ⊕ 0 = a
- a ⊕ b = b ⊕ a,交换律
- a ⊕b ⊕ c = a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c,结合律
- d = a ⊕ b ⊕ c 可以推出 a = d ⊕ b ⊕ c.
- a ⊕ b ⊕ a = b.
- a ⊕b=b ⊕c => a=b,消去律
相关题目
136. 只出现一次的数字(位运算)
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
思路:利用异或运算的性质,自己和自己异或结果为 0, 和 0 异或结果为本身
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/single-number/solution/zhi-chu-xian-yi-ci-de-shu-zi-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
res = 0
for num in nums:
res ^= num
return res