- Published on
LeetCode - Roman to Integer (13)
- Authors
- Name
- devnmin
Intuition
문제링크: https://leetcode.com/problems/roman-to-integer/description/
로마 숫자는 보통 왼쪽에서 오른쪽으로 값을 더하는 방식이지만,
특정 조합(예: IV, IX)은 앞 문자의 값이 더 작을 경우 감산해야 합니다.
이러한 특이 케이스들을 먼저 처리해주는 방식이 떠올랐습니다.
Approach
- 일반 문자(
I
,V
,X
등)의 값은 미리 딕셔너리로 매핑 - 특수한 2글자 조합(
IV
,IX
,CM
등)은 별도로 저장 - 반복문에서 문자열을 순회하면서 2글자 조합이 있는 경우 먼저 확인
- 있으면 해당 값을 더하고 인덱스를 2칸 이동, 없으면 1글자만 처리
Complexity
Time complexity:
(문자열 길이 n만큼 한 번씩 순회)Space complexity:
(고정된 딕셔너리와 상수 메모리만 사용)
Code (내 풀이)
mapping_values = {
"I": 1,
"V": 5,
"X": 10,
"L": 50,
"C": 100,
"D": 500,
"M": 1000,
}
matching_patterns = {
"IV": 4,
"IX": 9,
"XL": 40,
"XC": 90,
"CD": 400,
"CM": 900,
}
class Solution:
def romanToInt(self, s: str) -> int:
sum = 0
i = 0
while i < len(s):
is_set = False
if i != len(s) - 1:
for matching_pattern in matching_patterns:
if matching_pattern == s[i : i + 2]:
sum += matching_patterns[s[i : i + 2]]
i += 1
is_set = True
break
if not is_set:
sum += mapping_values[s[i]]
i += 1
return sum
# 🔧 AI 추천 리팩토링 개선버전
아래는 같은 로직을 더 간결하고 효율적으로 표현한 리팩토링 코드입니다.
✅ 개선된 코드
class Solution:
def romanToInt(self, s: str) -> int:
sum = 0
i = 0
while i < len(s):
if s[i:i+2] in matching_patterns:
sum += matching_patterns[s[i:i+2]]
i += 2
else:
sum += mapping_values[s[i]]
i += 1
return sum
✨ 개선 포인트
• for ... in 반복 없이 s[i:i+2] in dict로 체크 → 더 빠르고 간단
• is_set 플래그 제거로 코드가 더 읽기 쉬움
• 불필요한 딕셔너리 키 반복 제거
결과적으로, 시간복잡도는 여전히 $$O(n)$$ 이지만 평균 성능이 더 나아지고 코드 품질도 향상됩니다.
💡 Tip: 딕셔너리에서 키 존재 여부를 확인할 때는 key in dict를 활용하면 훨씬 효율적인 경우가 많습니다.