目录
罗马数字转整数
我们首先来看一道题目罗马数字转整数
罗马数字是一个字符串,字符组合代表数字的基本单元,有1000,500,100,50,10,5,1
从左到右依次从大到小,
那么我们只需要进行累加就可以了
但是需要注意,如4是IV,5是V,6是VI
观察到,比如4基准单元5小1,则I在前面,
如果是,表示90为XC,C在前面,
这个可以理解为先减去小的单元,再加上大的单元
所以我们在累加字符单元所代表数字时,需要判断当前字符代表数字是否比下个数字小,如果小,要减去当前数字,其他正常加
代码如下(python):
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
for (i, value) in enumerate(s):
currentValue = Solution.Symbol_Values[value]
n = len(s)
if(i < n-1 and currentValue < Solution.Symbol_Values[s[i+1]]):
ans = ans - currentValue
else:
ans = ans + currentValue
return ans
整数转罗马数字
那么我们来反向考虑这个问题整数转罗马数字
显然罗马数字比阿拉伯数字要笨拙一点,它采用字母来代表数字基准单元,如果表示数字比较大,就要记住相应的基数字母
当反向转化时,因为它是从左到右从大到小基准数字,
所以我们要从最大的基准数字依次比较,如果减不掉(小于)就比较下一个基准数字,直到把整数转化完,
需要注意的是基准数字不只是100,50,10,还有90,40,9,4这种
代码如下(python):
class Solution:
value_Symbols = [
('M', 1000),
('CM', 900),
('D', 500),
('CD', 400),
('C', 100),
('XC', 90),
('L', 50),
('XL', 40),
('X', 10),
('IX', 9),
('V', 5),
('IV', 4),
('I', 1)
]
def intToRoman(self, num: int) -> str:
RomanNum = list()
for (symbol, value) in Solution.value_Symbols:
while (num >= value):
num = num - value
RomanNum.append(symbol)
if (num == 0):
break
return ''.join(RomanNum)
我们使用字典记录罗马基准字母组合与数字的对应,
使用for循环以字典为基准进行遍历
整数反转
我们再来看一道题目,把整数数字进行反转整数反转
所谓把整数进行反转,是指从前到后的数字反转成从后到前,但是如果遇到末尾是0的情况,反转后开头就不会有0
那么假设要翻转的数是x,翻转后记为d,基本代码应是
d = 0
while(x):{
d = d *10 + x % 10
x = x // 10
}
所以while循环里只需要两行就可以解决这个问题。
题目中要求 如果翻转后的数字超过32 位的有符号整数的范围 [−231, 231 − 1]
,就返回 0
我们可以对翻转后的数字判断,如果超过这个范围,就返回0
代码如下(python):
class Solution:
def reverse(self, x: int) -> int:
flag = 1
if(x >= 0): flag = 1
else:
flag = -1
x = -x
INT_MIN, INT_MAX = -2 ** 31, 2**31 -1
y = 0
while(x):
digit = x % 10
x = x // 10
y = y*10 + digit
if(flag < 0): y = -y
if(y < INT_MIN or y > INT_MAX):
return 0
return y
回文数
我们最后来看一道题目 回文数
判断一个数是否是回文数,返回布尔值
一个数是回文数是指这个数正序(从左向右)读和倒序(从右向左)读是同一个数
那么我们的做法可以是两个索引,在左索引小于右索引的情况下,比较数字,如果相同,则继续比较,否则返回false
如果是回文字符串的话,就可以按照上述方式考虑,
但是,题目所给出的是一个数字
我们可以采用上题方式,将数进行翻转后进行比较
我们首先对一些明显的特别情况进行判断:
那么,如果是负数,由于负号的存在,一定不是回文数
如果这个数的末尾是0,由于开头不可能有0的存在,所以也一定是回文数
如果是0,是回文数,不需进行处理了,直接返回true
接下来,我们将数进行翻转,最后进行比较
还有一种我们不需要将所有位进行翻转,即翻转前的数为x,翻转后的数为rev,对x进行处理,在x>rev的情况下,
如果原来的数x是偶数位的,那么最后应该是比较x == rev
否则是奇数位的,比较x == rev // 10
代码如下:
class Solution:
def isPalindrome(self, x: int) -> bool:
if(x == 0):
return True
if(x < 0 or x % 10 == 0):
return False
rev = 0
while(x > rev):
rev = rev * 10 + x % 10
x = x// 10
return x == rev or x == rev // 10
参考题解: