Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
For example, 2 is written as II in Roman numeral, just two one’s added together. 12 is written as XII, which is simply X + II. The number 27 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.
Solution
First, let us look at the six instances, they are important for solving this problem.
We can find that number 4 and 9 will cause the special situations.
Normally, Roman numeral letters sort from large to small, but in special situations, it will not.
C# Solution
Solution1
public class Solution {
private readonly Dictionary<char, int> dict =
new Dictionary<char, int>{{'I',1},{'V',5},{'X',10},{'L',50},{'C',100},{'D',500},{'M',1000}};
public int RomanToInt(string s) {
char[] ch = s.ToCharArray();
int result = 0;
int intVal,nextIntVal;
for(int i = 0; i <ch.Length ; i++){
intVal = dict[ch[i]];
if(i != ch.Length-1)
{
nextIntVal = dict[ch[i+1]];
if(nextIntVal>intVal){
intVal = nextIntVal-intVal;
i = i+1;
}
}
result = result + intVal;
}
return result;
}
}
We can see if the next number is greater than the recent number, it means that it is a special situation if(nextIntVal>intVal) ➡ so recent number should be subtracted not added, and i = i+1 ➡ next number will be added this time and will skip to the number after it.
Solution2
public class Solution {
private readonly Dictionary<char, int> dict =
new Dictionary<char, int>{{'I',1},{'V',5},{'X',10},{'L',50},{'C',100},{'D',500},{'M',1000}};
public int RomanToInt(string s) {
//special situations
s = s.Replace("IV","IIII");
s = s.Replace("IX","VIIII");
s = s.Replace("XL","XXXX");
s = s.Replace("XC","LXXXX");
s = s.Replace("CD","CCCC");
s = s.Replace("CM","DCCCC");
int result = 0;
foreach(var ch in s)
{
result += dict[ch];
}
return result;
}
}
Replace the special situations, and just run an easy iteration and sum the numbers. Just that simple !
Java Solution
Solution1 (use map to store ➡ similar to C# dictionary )
class Solution {
public int romanToInt(String s) {
Map<Character, Integer> map = new HashMap<Character, Integer>() {{
put('I',1);
put('V',5);
put('X',10);
put('L',50);
put('C',100);
put('D',500);
put('M',1000);
}};
char[] arr = s.toCharArray();
int result = 0;
int intVal,nextIntVal;
for(int i = 0; i <arr.length ; i++){
intVal = map.get(arr[i]);
if(i != arr.length-1)
{
nextIntVal = map.get(arr[i+1]);
if(nextIntVal>intVal){
intVal = nextIntVal-intVal;
i = i+1;
}
}
result = result + intVal;
}
return result;
}
}
⭐Runtime : 9ms、9ms、12ms ➡ average 10 ms
Solution2
class Solution {
public int romanToInt(String s) {
Map<Character, Integer> map = new HashMap<Character, Integer>() {{
put('I',1);
put('V',5);
put('X',10);
put('L',50);
put('C',100);
put('D',500);
put('M',1000);
}};
//special situations
s = s.replace("IV","IIII");
s = s.replace("IX","VIIII");
s = s.replace("XL","XXXX");
s = s.replace("XC","LXXXX");
s = s.replace("CD","CCCC");
s = s.replace("CM","DCCCC");
int result = 0;
for (char ch: s.toCharArray()) {
result+= map.get(ch);
}
return result;
}
}
Runtime : 14ms、20ms、14ms ➡ average 16 ms
Python3 Solution
Solution1
class Solution:
def romanToInt(self, s: str) -> int:
dict = {
'I' : 1,
'V' : 5,
'X' : 10,
'L' : 50,
'C' : 100,
'D' : 500,
'M' : 1000
}
result = 0
tmp = 0;
i = 0
while i < len(s):
tmp = dict[s[i]];
if (i +1) < len(s) and dict[s[i]] < dict[s[i + 1]]:
tmp = dict[s[i + 1]] - dict[s[i]]
i += 1
i += 1
result += tmp;
return (result)
Solution2
class Solution:
def romanToInt(self, s: str) -> int:
dict = {
'I' : 1,
'V' : 5,
'X' : 10,
'L' : 50,
'C' : 100,
'D' : 500,
'M' : 1000
}
s = s.replace("IV","IIII").replace("IX","VIIII");
s = s.replace("XL","XXXX").replace("XC","LXXXX");
s = s.replace("CD","CCCC").replace("CM","DCCCC");
result = 0;
for i in range(len(s)):
result += dict[s[i]];
return (result)
JavaScript Solution
Solution1 (use dictionary and next Roman numeral to check add or subtract)
/**
* @param {string} s
* @return {number}
*/
var romanToInt = function(s) {
var dict = {
'I':1,
'V':5,
'X':10,
'L':50,
'C':100,
'D':500,
'M':1000
};
var result = 0;
var intVal = 0;
var nextIntVal = 0;
for (var i = 0; i < s.length; i++) {
intVal = dict[s[i]];
if(i!=s.length-1)
{
nextIntVal = dict[s[i+1]];
if(nextIntVal>intVal){
intVal = nextIntVal-intVal;
i = i+1;
}
}
result = result + intVal;
}
return result;
};
Test Runtime – 208 ms, faster than 35.78% 、172 ms, faster than 60.74% 、195 ms, faster than 45.00% ➡ average 192 ms
Solution2 (replace special situations)
/**
* @param {string} s
* @return {number}
*/
var romanToInt = function(s) {
var dict = {
'I':1,
'V':5,
'X':10,
'L':50,
'C':100,
'D':500,
'M':1000
};
s = s.replace("IV","IIII").replace("IX","VIIII");
s = s.replace("XL","XXXX").replace("XC","LXXXX");
s = s.replace("CD","CCCC").replace("CM","DCCCC");
var result = 0;
for (var i = 0; i < s.length; i++) {
result+=dict[s[i]];
}
return result;
};
Test Runtime – 201 ms, faster than 40.72% 、140 ms, faster than 80.10% 、183 ms, faster than 53.61%
➡ average 175 ms
Conclusion
This problem is the first problem I solved in LeetCode, and I took a while to find out the answer.
After some optimization, now the running speed seems just ok.
🧡If my solution helps, that is my honor!
🧡You can support me by clicking some ad, Thanks a lot!
while i < len(s):
tmp = dict[s[i]];
if (i +1) < len(s) and dict[s[i]] < dict[s[i + 1]]:
tmp = dict[s[i + 1]] – dict[s[i]]
i += 1
i += 1
result += tmp;
return (result)
I gave the input as IV.
Now when the len(s) =2 so when i=1 in the second iteration shouldn't "dict[s[i]] < dict[s[i + 1]]" this give an IndexError: string index out of range? since s[2] doesn't exist?
I think you are talking about the solution1 of Python3 code!
Sure, s[2] doesn’t exist, because the len of IV is 2.
But in this case i will add i+=1 after the condition 【if (i +1) < len(s) and dict[s[i]] < dict[s[i + 1]]:】 >> 【(0+1)<1 and 1<5】➡ i=1
And out of the if condition, it will be add again ➡ i=2
So in this case, the next iteration will be break 【while i < len(s):】 >> 【2<2】will get false and break!
The IndexError will not happen in this case.
Hope the explanation helps you !
var romanToInt = function(s) {
const dict = {
‘I’:1,
‘V’:5,
‘X’:10,
‘L’:50,
‘C’:100,
‘D’:500,
‘M’:1000
};
var result = 0;
var intVal = 0;
var nextIntVal = 0;
for(i = 0; i < s.length; i++) {
intVal = dict[s[i]];
var uagb_data = {"ajax_url":"https:\/\/zyrastory.com\/wp-admin\/admin-ajax.php","uagb_masonry_ajax_nonce":"e5d570c704"};
var uagb_data = {"ajax_url":"https:\/\/zyrastory.com\/wp-admin\/admin-ajax.php","uagb_masonry_ajax_nonce":"e5d570c704","uagb_grid_ajax_nonce":"42d973fdc9"};
( function() {
let elements = document.querySelectorAll( '.uagb-post-grid.uagb-block-b188ba42 .uagb-post-pagination-wrap a' );
elements.forEach(function(element) {
element.addEventListener("click", function(event){
event.preventDefault();
const link = event.target.getAttribute('href').match( /\/page\/\d+\// )?.[0] || '';
const regex = /\d+/; // regular expression to match a number at the end of the string
const match = link.match( regex ) ? link.match( regex )[0] : 1; // match the regular expression with the link
const pageNumber = parseInt( match ); // extract the number and parse it to an integer
window.UAGBPostGrid._callAjax({"btnBorderStyle":"none","overallBorderColor":"","block_id":"b188ba42","categories":"62","displayPostExcerpt":false,"displayPostComment":false,"displayPostImage":false,"imgSize":"medium","linkBox":false,"orderBy":"rand","excludeCurrentPost":true,"postPagination":true,"pageLimit":0,"imageRatio":"2-3","imgEqualHeight":true,"btnBorderLink":true,"btnBorderRadiusLink":true,"overallBorderLink":true,"overallBorderRadiusLink":true,"inheritFromTheme":true,"postType":"post","postDisplaytext":"No post found!","taxonomyType":"category","postsToShow":6,"enableOffset":false,"postsOffset":0,"displayPostDate":true,"excerptLength":15,"displayPostAuthor":false,"displayPostTitle":true,"displayPostTaxonomy":false,"hideTaxonomyIcon":true,"taxStyle":"default","displayPostTaxonomyAboveTitle":"withMeta","imgPosition":"top","bgOverlayColor":"#000000","overlayOpacity":"50","displayPostLink":true,"newTab":false,"ctaText":"Read More","inheritFromThemeBtn":false,"buttonType":"primary","btnHPadding":"","btnVPadding":"","columns":3,"tcolumns":2,"mcolumns":1,"align":"left","width":"wide","order":"desc","rowGap":20,"rowGapTablet":20,"rowGapMobile":20,"columnGap":20,"bgType":"color","bgColor":"#f6f6f6","titleTag":"h4","titleFontSize":"","titleFontSizeType":"px","titleFontFamily":"","titleLineHeightType":"em","titleLoadGoogleFonts":false,"metaColor":"","highlightedTextColor":"#fff","highlightedTextBgColor":"#3182ce","metaFontSize":"","metaFontSizeType":"px","metaFontFamily":"","metaLineHeightType":"em","metaLoadGoogleFonts":false,"excerptColor":"","excerptFontSize":"","excerptFontSizeType":"px","excerptFontFamily":"","excerptLineHeightType":"em","excerptLoadGoogleFonts":false,"displayPostContentRadio":"excerpt","ctaBgType":"color","ctaBgHType":"color","ctaFontSize":"","ctaFontSizeType":"px","ctaFontFamily":"","ctaLineHeightType":"em","ctaLoadGoogleFonts":false,"paddingTop":20,"paddingBottom":20,"paddingRight":20,"paddingLeft":20,"contentPadding":20,"ctaBottomSpace":0,"ctaBottomSpaceTablet":0,"ctaBottomSpaceMobile":0,"imageBottomSpace":15,"titleBottomSpace":15,"metaBottomSpace":15,"excerptBottomSpace":25,"contentPaddingUnit":"px","rowGapUnit":"px","columnGapUnit":"px","excerptBottomSpaceUnit":"px","paginationSpacingUnit":"px","imageBottomSpaceUnit":"px","titleBottomSpaceUnit":"px","metaBottomSpaceUnit":"px","ctaBottomSpaceUnit":"px","paddingBtnUnit":"px","mobilePaddingBtnUnit":"px","tabletPaddingBtnUnit":"px","paddingUnit":"px","mobilePaddingUnit":"px","tabletPaddingUnit":"px","isPreview":false,"taxDivider":", ","titleLetterSpacing":"","titleLetterSpacingType":"px","metaLetterSpacing":"","metaLetterSpacingType":"px","ctaLetterSpacing":"","ctaLetterSpacingType":"px","excerptLetterSpacing":"","excerptLetterSpacingType":"px","useSeparateBoxShadows":true,"boxShadowColor":"#00000070","boxShadowHOffset":0,"boxShadowVOffset":0,"boxShadowBlur":"","boxShadowSpread":"","boxShadowPosition":"outset","boxShadowColorHover":"","boxShadowHOffsetHover":0,"boxShadowVOffsetHover":0,"boxShadowBlurHover":"","boxShadowSpreadHover":"","boxShadowPositionHover":"outset","borderWidth":"","borderStyle":"none","borderColor":"","borderRadius":"","blockName":"post-grid","equalHeight":true,"paginationBgActiveColor":"#e4e4e4","paginationActiveColor":"#333333","paginationBgColor":"#e4e4e4","paginationColor":"#777777","paginationMarkup":"","paginationLayout":"filled","paginationBorderColor":"#888686","paginationBorderSize":1,"paginationSpacing":20,"paginationAlignment":"left","paginationPrevText":"\u00ab Previous","paginationNextText":"Next \u00bb","layoutConfig":[["uagb\/post-image"],["uagb\/post-taxonomy"],["uagb\/post-title"],["uagb\/post-meta"],["uagb\/post-excerpt"],["uagb\/post-button"]],"post_type":"grid","equalHeightInlineButtons":false,"paginationType":"ajax","isLeftToRightLayout":false,"wrapperTopPadding":"","wrapperRightPadding":"","wrapperLeftPadding":"","wrapperBottomPadding":"","wrapperTopPaddingTablet":"","wrapperRightPaddingTablet":"","wrapperLeftPaddingTablet":"","wrapperBottomPaddingTablet":"","wrapperTopPaddingMobile":"","wrapperRightPaddingMobile":"","wrapperLeftPaddingMobile":"","wrapperBottomPaddingMobile":"","wrapperPaddingUnit":"px","wrapperPaddingUnitTablet":"px","wrapperPaddingUnitMobile":"px","wrapperPaddingLink":false,"wrapperAlign":"row","wrapperAlignPosition":"center","extended_widget_opts_block":{},"extended_widget_opts":{},"extended_widget_opts_state":"","extended_widget_opts_clientid":"","dateUpdated":""}, pageNumber, 'b188ba42');
});
});
} )();
ai_front = {"insertion_before":"BEFORE","insertion_after":"AFTER","insertion_prepend":"PREPEND CONTENT","insertion_append":"APPEND CONTENT","insertion_replace_content":"REPLACE CONTENT","insertion_replace_element":"REPLACE ELEMENT","visible":"VISIBLE","hidden":"HIDDEN","fallback":"FALLBACK","automatically_placed":"Automatically placed by AdSense Auto ads code","cancel":"Cancel","use":"Use","add":"Add","parent":"Parent","cancel_element_selection":"Cancel element selection","select_parent_element":"Select parent element","css_selector":"CSS selector","use_current_selector":"Use current selector","element":"ELEMENT","path":"PATH","selector":"SELECTOR"};
dict = {
‘I’ : 1,
‘V’ : 5,
‘X’ : 10,
‘L’ : 50,
‘C’ : 100,
‘D’ : 500,
‘M’ : 1000
}
result = 0
tmp = 0;
i = 0
while i < len(s):
tmp = dict[s[i]];
if (i +1) < len(s) and dict[s[i]] < dict[s[i + 1]]:
tmp = dict[s[i + 1]] – dict[s[i]]
i += 1
i += 1
result += tmp;
return (result)
I gave the input as IV.
Now when the len(s) =2 so when i=1 in the second iteration shouldn't "dict[s[i]] < dict[s[i + 1]]" this give an IndexError: string index out of range? since s[2] doesn't exist?
I think you are talking about the solution1 of Python3 code!
Sure, s[2] doesn’t exist, because the len of IV is 2.
But in this case i will add i+=1 after the condition 【if (i +1) < len(s) and dict[s[i]] < dict[s[i + 1]]:】 >> 【(0+1)<1 and 1<5】➡ i=1
And out of the if condition, it will be add again ➡ i=2
So in this case, the next iteration will be break 【while i < len(s):】 >> 【2<2】will get false and break!
The IndexError will not happen in this case.
Hope the explanation helps you !
var romanToInt = function(s) {
const dict = {
‘I’:1,
‘V’:5,
‘X’:10,
‘L’:50,
‘C’:100,
‘D’:500,
‘M’:1000
};
var result = 0;
var intVal = 0;
var nextIntVal = 0;
for(i = 0; i < s.length; i++) {
intVal = dict[s[i]];
if(i != s.length – 1) {
if(nextIntVal<intVal) {
nextIntVal = dict[s[i+1]];
intVal = intVal – nextIntVal;
i = i + 1;
}
}
result = result + intVal;
}
return result;
};