12
题目描述:
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
示例:
解答:
m = [
['', 'M', 'MM', 'MMM'],
['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'],
['', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'],
['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX']
]
d = [1000, 100, 10, 1]
r = ''
for k, v in enumerate(d):
r += m[k][int(num/v)]
num = num % v
return r
17
题目描述:
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
解答:
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
KEY = {'2': ['a', 'b', 'c'],
'3': ['d', 'e', 'f'],
'4': ['g', 'h', 'i'],
'5': ['j', 'k', 'l'],
'6': ['m', 'n', 'o'],
'7': ['p', 'q', 'r', 's'],
'8': ['t', 'u', 'v'],
'9': ['w', 'x', 'y', 'z']}
if digits == '':
return []
ans = ['']
for num in digits:
ans = [pre+suf for pre in ans for suf in KEY[num]]
return ans
46
题目描述:
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
解答:
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
#回溯算法
res = []
def backtrack(nums, tmp):
if not nums:
res.append(tmp)
return
for i in range(len(nums)):
backtrack(nums[:i] + nums[i+1:], tmp + [nums[i]])
backtrack(nums, [])
return res
131
题目描述:
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例;
解答:
class Solution:
def partition(self, s: str) -> List[List[str]]:
'''
用回溯递归的方法去试探每一种可能性
对于一个字符串s,有len(s)种方法把它分成左右两个部分(分割方法看代码),
假如左侧的不是回文,则舍弃这次尝试;
假如左侧的是回文串,则把右侧的进行递归的分割,并返回右侧的分割的所有情况
'''
if len(s) == 0:
return [[]]
if len(s) == 1:
return [[s]]
tmp = []
for i in range(1,len(s)+1):
left = s[:i]
right = s[i:]
if left ==left[::-1]: #如果左侧不是回文的,则舍弃这种尝试
right = self.partition(right)
for i in range(len(right)):
tmp.append([left]+right[i])
return tmp
204
题目描述:
统计所有小于非负整数 n 的质数的数量。
示例:
解答:
class Solution:
def countPrimes(self, n: int) -> int:
'''
厄拉多塞筛法.
比如说求20以内质数的个数,首先0,1不是质数.
2是第一个质数,然后把20以内所有2的倍数划去.
2后面紧跟的数即为下一个质数3,然后把3所有的倍数划去.
3后面紧跟的数即为下一个质数5,再把5所有的倍数划去.
以此类推.
'''
if n < 3:
return 0
else:
# 首先生成了一个全部为1的列表
output = [1] * n
# 因为0和1不是质数,所以列表的前两个位置赋值为0
output[0],output[1] = 0,0
# 此时从index = 2开始遍历,output[2]==1,即表明第一个质数为2,然后将2的倍数对应的索引
# 全部赋值为0. 此时output[3] == 1,即表明下一个质数为3,同样划去3的倍数.以此类推.
for i in range(2,int(n**0.5)+1):
if output[i] == 1:
output[i*i:n:i] = [0] * len(output[i*i:n:i])
# 最后output中的数字1表明该位置上的索引数为质数,然后求和即可.
return sum(output)
'''
上面遍历索引的时候用到了一个非常好的技巧.
即i是从(2,int(n**0.5)+1)而非(2,n).
这个技巧是可以验证的,
比如说求9以内的质数个数,那么只要划掉sqrt(9)以内的质数倍数,剩下的即全为质数.
所以在划去倍数的时候也是从i*i开始划掉,而不是i+i.
'''