题目7
解法1
【算法思路】:
① 使用列表,将输入数字的每一位从个位起依次存入列表;
② 对列表中的0元素进行处理,然后将列表的元素变为数字输出;
③ 根据条件返回对应的翻转数字;
④ 算法复杂度为O(n),较高。
【代码】:
class Solution:
def reverse(self, x):
"""
type x: int
rtype : int
"""
nums = []
if x == 0: # 0的翻转为0
return 0
x_ = abs(x) # 无论正负都先按照正数处理
while x_ > 0: # 将输入整数的每一位存入到列表里
#nums[i] = x_ % 10 列表为空时不能赋值
nums.append(x_%10)
x_ = x_ // 10
for i in range(len(nums)):# 对0元素进行处理
if nums[0] != 0:
break
else:
nums.pop(0)
if eval(''.join(str(t) for t in nums)) > math.pow(2,31):# 判断翻转后的数字是否越界
return 0
if x > 0: # 根据正负数返回不同的数值
return(eval(''.join(str(t) for t in nums)))
else:
return(eval("-"+(''.join(str(t) for t in nums))))
【测试截图】:
解法2
【算法思路】:
① 将整数先转化为字符;
② 对字符使用切片操作进行翻转;
③ 再将字符串转化为整数后根据条件输出翻转的数;
④ 用了切片操作,其算法复杂度为O(n)
【代码】:
class Solution:
def reverse(self, x):
"""
type x: int
rtype : int
"""
if x >= 0:
reversed_x = int(str(x)[::-1])
else:
reversed_x = -int(str(x)[:0:-1]) # 不加负号在本地编译器上可以通过,在LeetCode上没有过
if -math.pow(2, 31) < reversed_x < math.pow(2, 31) - 1:
return reversed_x
else:
return 0
【测试截图】:
题目66
解法1
【算法思路】:
① 分情况进行处理:最后一位数字不是9,最后一位数字是9且9的个数和数字位数相等,最后一位是9但9 的个数和数字位数不相等;
② 如果最后一位不是9,那么直接在最后一位加一后输出;
③ 如果整数全是9,如9, 99, 999, 9999…那么将第一位赋值为1,后面全为0,在 加一个零;
④ 如果整数不全是9,在从后往前第一个不是9的数字上加一,后面的数字全部另为0
【代码】:
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
"""
type digits: List[int]
rtype: List[int]
"""
num = 0
if digits[-1] != 9: # 如果最后一位不是9,那么直接在最后一位加一后输出
digits[-1] += 1
return digits
for i in range(len(digits)):# 如果整数带9,首先从最后一位开始计算9的个数num
if digits[-1-i] == 9:
num += 1
else:
break
if num == len(digits): # 如果整数全是9,如9,99,999,9999......那么将第一位赋值为1,后面全为0,在 加一个零
digits[0] = 1
for i in range(len(digits)-1):
digits[-1-i] = 0
digits.append(0)
else: # 否则的话在从后往前第一个不是9的数字上加一,后面的数字全部另为0
digits[-1-num] += 1
for i in range(num):
digits[-1-i] = 0
return digits
【测试截图】:
解法2
【算法思路】:更聪明、优雅、简洁的做法
① 将解法1中的情况1和3合并到一起,并且使用取模的做法,通过有进位的数字判断9,无需先行计算9的个数,更简单。
② 算法过程为:从最后一位开始依次往前遍历,依次判断每一位加1之后是否有进位,直到没有进位时,返回数字加1;否则首位变1,末位加0;
③ 算法复杂度:O(n)。
【代码】:
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
"""
type digits: List[int]
rtype: List[int]
"""
for i in range(len(digits)-1, -1, -1):# 从最后一位开始依次往前遍历
digits[i] += 1 # 依次判断每一位加1之后是否有进位
digits[i] = digits[i] % 10 # 直到没有进位时,返回数字加1
if digits[i] != 0: # 情况:187,1899......
return digits
digits[0] = 1 # 情况:9, 99, 999......首位变1,末尾加0
digits.append(0)
return digits
【测试截图】:
题目13
解法1
【算法思路】:
① 将基本字符存入字典中;
② 从后往前遍历输入的字符串,从最后一个字符开始前后两两比较,看是否为特殊情况(右边的数大于左边的数);
③ 为了保证两两判断的可行性,对遍历的字符下标做规定,以保证不会产生索引越界的情况,即遍历的索引不能大于len(s)-1,这样才能保证最多取到s[0];
④ 对于s[1]s[2]是特殊情况时,单独对s[0]做处理。
【代码】:
class Solution:
def romanToInt(self, s: str) -> int:
"""
type s: str
rtype: int
"""
sum = 0
i = 0
dict = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000} # 字典定义基本字符
while i < len(s): # 从后往前遍历字符串
if i < (len(s)-1): # 保证始终能进行前后比较,不能出现s[-len(s)-1]的情况,即最多只能到s[0]
if dict[s[-1-i]] > dict[s[-1-i-1]]:
sum += (dict[s[-1-i]] - dict[s[-1-i-1]])
i += 2
continue
else:
sum += dict[s[-1-i]]
i += 1
continue
else: # s[1]s[2]是特殊情况,即存在s[0]时,将s[0]加上去
sum += dict[s[0]]
i += 1
continue
return sum
【测试截图】:
解法2:透过现象看本质
【算法思路】:
① 当罗马数字中小数字在大数字左边时,大数字-小数字(eg. IV = 4),否则,大数字+小数字(eg. VI = 6);
② 对每一位字符与其下一位字符进行判断,判断到s[-2]结束;
③ 最后加上s[-1]。
【注】罗马数字的正确性保证了不会出现题目外其他的小数字在大数字左边的情况以及连续两组(3个罗马数字)小数字在大数字左边的情况。
【代码】:
class Solution:
def romanToInt(self, s: str) -> int:
"""
type s: str
rtype: int
"""
sum = 0
dict = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000} # 字典定义基本字符
for i in range(len(s)-1):
if dict[s[i]] < dict[s[i+1]]: # 小数字在大数字左边
sum -= dict[s[i]]
else: # 小数字在大数字右边
sum += dict[s[i]]
sum += dict[s[-1]]
return sum
【测试截图】: