Roman to Integer, Integer to Roman, ZigZag Conversion

Roman to Integer

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

Solution

How roman numbers work:

M | D | C | L | X | V | I |

1000 | 500 | 100 | 50 | 10 | 5 | 1 |

If the current character is larger than previous one, then we substract previous form current, otherwise add up all digits.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public int romanToInt(String s) {
if(s==null) return 0;
int n=s.length(),res=0;
for(int i=0 ; i< n;i++){
switch(s.charAt(i)){
case 'I':
if(i<n-1 && s.charAt(i+1)!='I'){res-=1;break;}
else{res+=1; break;}
case 'V':
if(i<n-1 && s.charAt(i+1)!='I'){res-=5;break;}
else {res+=5; break;}
case 'X':
if(i<n-1 && (s.charAt(i+1)=='L'||s.charAt(i+1)=='C'||s.charAt(i+1)=='D'||s.charAt(i+1)=='M')){res-=10;break;}
else {res+=10; break;}
case 'L':
if(i<n-1 && (s.charAt(i+1)=='C'||s.charAt(i+1)=='D'||s.charAt(i+1)=='M')){res-=50;break;}
else {res+=50; break;}
case 'C':
if(i<n-1 && (s.charAt(i+1)=='D'||s.charAt(i+1)=='M')){res-=100; break;}
else {res+=100;break;}
case 'D':
if(i<n-1 && s.charAt(i+1)=='M') {res-=500; break;}
else {res+=500; break;}
case 'M': res+=1000; break;
}
}
return res;
}

Integer to Roman

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

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public String intToRoman(int num) {
int[] numbers={1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] tokens={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
StringBuilder sb=new StringBuilder();
int i=0;
while(num>0){
int tmp=num/numbers[i];
num=num-tmp*numbers[i];
for(int k=tmp;k>=1;k--){
sb.append(tokens[i]);
}
i++;
}
return sb.toString();
}

ZigZag Conversion

The string “PAYPALISHIRING” is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

1
2
3
P A H N
A P L S I I G
Y I R

And then read line by line: “PAHNAPLSIIGYIR”
Write the code that will take a string and make this conversion given a number of rows:
string convert(string text, int nRows);
convert(“PAYPALISHIRING”, 3) should return “PAHNAPLSIIGYIR”.

Solution

Each group of words are 2*nRows-2, we add the String row by row. Be careful about first and last row:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public String convert(String s, int nRows) {
int nCol=0,size=2*nRows-2;
if(s==null || nRows==1) return s;
StringBuilder res=new StringBuilder();
//add char to stringbuilder row by row
for(int i=0;i<nRows;i++){
for(int j=i;j<s.length();j+=size){
res.append(s.charAt(j));
if(i!=0 && i!=nRows-1 && j+size-2*i<s.length())
res.append(s.charAt(j+size-2*i));
}
}
return res.toString();
}