内容来自LeetCode,使用Python完成
1. 3的幂
题目要求
给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 3 的幂次方需满足:存在整数 x 使得 n == 3x
示例 1:
输入:n = 27
输出:true
示例 2:
输入:n = 0
输出:false
示例 3:
输入:n = 9
输出:true
示例 4:
输入:n = 45
输出:false
进阶:你能不使用循环或者递归来完成本题吗?
思路
比较直观的可以想到可以用n一直除以3,如果有余则说明为False。还有一种办法是用从小开始遍历3的幂,遍历至与n相等则为True,如果遍历至大于n,则为False。两种思路都是比较暴力的解法。
#从小开始遍历3的幂
class Solution:
def isPowerOfThree(self, n: int) -> bool:
if n == 1:
return True
mi = 1
flag = 0
while mi < n:
mi = mi * 3
if mi == n:
flag = 1
if flag == 1:
return True
else:
return False
#n持续除以3
class Solution:
def isPowerOfThree(self, n: int) -> bool:
if n == 0 :
return False
while n != 1:
if n%3 != 0:
return False
n = n / 3
return True
上面两种解法都还行,一个时间比较快一个内存占用比较小。下面再用递归尝试实现上面两种解法。
#n持续除以3 的递归实现
class Solution:
def isPowerOfThree(self, n: int) -> bool:
def digui(n: int) -> bool :
if n == 1:
return True
if n % 3 != 0 or n == 0:
return False
else:
return digui(n/3)
return digui(n)
官方题解的另一种办法为判断是否为最大3的幂的约数。题解论述如下:
在题目给定的 32位有符号整数的范围内,最大的 3 的幂为 3^{19} = 1162261467。我们只需要判断 n 是否是 3^{19}的约数即可。。。确实比较取巧
class Solution:
def isPowerOfThree(self, n: int) -> bool:
return n > 0 and 1162261467 % n == 0
2. 罗马数字转整数
题目要求
罗马数字包含以下七种字符: 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。
给定一个罗马数字,将其转换成整数。
思路
在没有特殊规则的情况下,很容易想到可以用多个if语句来解决(其实更直接想到了C 中的switch 语句,python3.10增加了类似的match...case 的条件判断,更为方便)。但是由于有特殊情况的存在,需要做更多的限制来准备转换。
class Solution:
def romanToInt(self, s: str) -> int:
num = 0
for i in range(len(s)):
if s[i] == 'I':
num += 1
if s[i] == 'V':
if i == 0:
num += 5
elif s[i-1] == 'I':
num += 3
else:
num += 5
if s[i] == 'X':
if i == 0:
num += 10
elif s[i-1] == 'I':
num += 8
else:
num += 10
if s[i] == 'L':
if i == 0:
num += 50
elif s[i-1] == 'X':
num += 30
else:
num += 50
if s[i] == 'C':
if i == 0:
num += 100
elif s[i-1] == 'X':
num += 80
else:
num += 100
elif s[i] == 'D':
if i == 0:
num += 500
elif s[i-1] == 'C':
num += 300
else:
num += 500
elif s[i] == 'M':
if i == 0:
num += 1000
elif s[i-1] == 'C':
num += 800
else:
num += 1000
return num
虽然写的很麻烦,但是实际运行结果也还行。
接下来是学习的解法
官方解题
通常情况下,罗马数字中小的数字在大的数字的右边。若输入的字符串满足该情况,那么可以将每个字符视作一个单独的值,累加每个字符对应的数值即可。
若存在小的数字在大的数字的左边的情况,根据规则需要减去小的数字。对于这种情况,我们也可以将每个字符视作一个单独的值,若一个数字右侧的数字比它大,则将该数字的符号取反。(同时还用到了字典)
class Solution:
SYMBOL_VALUES = {
'I': 1,
'V': 5,
'X': 10,
'L': 50,
'C': 100,
'D': 500,
'M': 1000,
}
def romanToInt(self, s: str) -> int:
ans = 0
n = len(s)
for i, ch in enumerate(s):
value = Solution.SYMBOL_VALUES[ch]
if i < n - 1 and value < Solution.SYMBOL_VALUES[s[i + 1]]:
ans -= value
else:
ans += value
return ans
另有人提出使用正则表达式来解决
先空着
上述解题都是从左向右来看的,有人提出可以从右向左遍历,纪录遇到的最大的数字,遇到更大的加,遇到小的减。
class Solution:
def romanToInt(self, s: str) -> int:
roman = {
'I': 1,
'V': 5,
'X': 10,
'L': 50,
'C': 100,
'D': 500,
'M': 1000,
}
num = 0
highest = 0
for i in s[::-1]:
if highest <= roman[i]:
num += roman[i]
highest = roman[i]
else:
num -= roman[i]
return num
文章介绍了如何使用Python解决LeetCode上的两个问题:判断一个整数是否为3的幂次方,以及将罗马数字转换为整数。对于3的幂次方问题,提供了除法和遍历3的幂的方法,以及递归实现。罗马数字转整数的解法包括逐字符处理和考虑特殊情况的转换规则。
168万+

被折叠的 条评论
为什么被折叠?



