leetcode 13. Roman to Integer 解法 python3

一.问题描述

Roman numerals are represented by seven different symbols: IVXLCD and M.

Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

  • I can be placed before V (5) and X (10) to make 4 and 9. 
  • X can be placed before L (50) and C (100) to make 40 and 90. 
  • C can be placed before D (500) and M (1000) to make 400 and 900.

Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.

Example 1:

Input: "III"
Output: 3

Example 2:

Input: "IV"
Output: 4

Example 3:

Input: "IX"
Output: 9

Example 4:

Input: "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.

Example 5:

Input: "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

二.解题思路

方法1:

罗马数字一般来说都是左边的比右边的大。

例外的6个情况已经列出来。

我们直接遍历数组,判断s[i]代表的数字是否大于s[i-1],不是的话直接累加,是的话要把s[i-1]代表的值从累加的结果中减去不且还要再减一次,然后再加上s[i]。

时间复杂度:O(N),空间复杂度:O(1)

我们只需要跟踪前后2个数的状态就行了,因为不存在s[i-1]<s[i]<s[i+1]>s[i+2](1)或者s[i-1]<s[i]<s[i+1]<s[i+2](2)的情况,情况1 s[i+1]和s[i+2]并不在特殊情况中,s[i+1]必然>s[i]>s[i-1]s[i],因此应该在s[i-1]左边因为他大。同理情况2。

方法2:

你也可以直接计算 I, X等和6个特例情况罗马字符在数组中的出现次数,然后求和。注意以下单独元素和特定元素有重复元素情况下计算单个元素的个数。比如I 和 IV, IV中的I在计数时也算在I里了,所以计算I次数的时候要减掉IV中的I,这方法比上面慢。

方法3:

把6个特殊情况单独拿出来处理,相加完后在字符串中替换掉,剩下的字符串就是没有特殊情况的罗马数字,直接加。

当然也会比较慢。

更多leetcode算法题解法: 专栏 leetcode算法从零到结束

三.源码

方法1:

class Solution:
    def romanToInt(self, s: str) -> int:
        rom2num={'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
        res=rom2num[s[0]]
        for i in range(1,len(s)):
            res+=rom2num[s[i]]-2*rom2num[s[i-1]] if rom2num[s[i]]>rom2num[s[i-1]] else rom2num[s[i]]
        return res

方法2:https://leetcode.com/problems/roman-to-integer/discuss/422150/Python-One-Liner

方法3:https://leetcode.com/problems/roman-to-integer/discuss/423025/python-3-solution

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!对于LeetCode上的问题994.腐烂的橘子,你可以使用Python来解决。下面是一个示例代码: ```python from collections import deque def orangesRotting(grid): # 记录网格的行数和列数 row, col = len(grid), len(grid[0]) # 定义四个方向:上、下、左、右 directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 使用队列来保存腐烂的橘子的位置 queue = deque() # 记录新鲜橘子的数量 fresh_count = 0 # 遍历整个网格,初始化队列和新鲜橘子的数量 for i in range(row): for j in range(col): if grid[i][j] == 2: # 腐烂的橘子 queue.append((i, j)) elif grid[i][j] == 1: # 新鲜橘子 fresh_count += 1 # 如果新鲜橘子的数量为0,直接返回0 if fresh_count == 0: return 0 # 初始化分钟数 minutes = 0 # 开始进行BFS,直到队列为空 while queue: # 记录当前分钟数下,队列中的元素数量 size = len(queue) # 遍历当前分钟数下的所有腐烂的橘子 for _ in range(size): x, y = queue.popleft() # 遍历四个方向 for dx, dy in directions: nx, ny = x + dx, y + dy # 判断新位置是否在网格内,并且是新鲜橘子 if 0 <= nx < row and 0 <= ny < col and grid[nx][ny] == 1: # 将新鲜橘子变为腐烂状态 grid[nx][ny] = 2 # 将新鲜橘子的位置加入队列 queue.append((nx, ny)) # 新鲜橘子的数量减1 fresh_count -= 1 # 如果当前分钟数下,没有新鲜橘子了,结束循环 if fresh_count == 0: break # 每遍历完一层,分钟数加1 minutes += 1 # 如果最后还有新鲜橘子,返回-1,否则返回分钟数 return -1 if fresh_count > 0 else minutes ``` 你可以将给定的网格作为参数传递给`orangesRotting`函数来测试它。请注意,该代码使用了BFS算法来遍历橘子,并计算腐烂的分钟数。希望能对你有所帮助!如果有任何疑问,请随时问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值