これは、喜びと喜びの最初の本である351、最初の更新376ピアンオリジナル
01の質問と準備ができて見えます
今日導入されLeetCodeにおけるアルゴリズムの問題中のレベル6(全体のタイトル番号があるタイトル12)。7つの異なるシンボルのローマ数字:I、V、X、L 、C、D 及びM.
符号 值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例えば、ローマ数字2で書かれたII
、私は2つで加算しました。12は、書かれたXII
短いため、X + II
。
27書かれXXVII
、それがありますXX + V + II
。
ローマ数字は、通常、最大から最小へ、左から右にされています。しかし、代わりに4つの数字のIIII
。対照的に、図4は、書かれましたIV
。
そのためI
にV
、我々は引き算4を行うために取得する前に。同じ原理が書かれている9,9に適用されますIX
。減算の使用の6件のインスタンスがあります。
I
それを配置することができるV
(5)及びX
前(10)に、4及び9を得ました。
X
配置することができるL
(50)とC
40及び90を与えるために、前(100)。
C
それは置くことができるD
(500)及びM
(1000)の前に、400および900を得ました。
整数を考えると、ローマ数字に変換します。入力は3999から1の範囲にあることを保証します。例えば:
入力:3
出力: "III"
入力:4
出力: "IV"
入力:9
出力: "IX"
入力:58
出力: "LVIII"
説明:L = 50、V = 5 、III = 3。
入力:1994
出力: "MCMXCIV"
説明:M = 1000、CM = 900 、XC = 90、IV = 4。
02第一溶液
トピックの要件は、私たちは反対に遭遇する前に文字列の数を整数にローマ、ローマを表現するために、文字列の整数に変わります。
タイトルは、NUMの範囲を規定する[1,3999]
共通デジタルのために、以下に列挙したものローマと整数との間の関係:
900 CM 90 XC 9 IX
800 DCCC 80 LXXX 8 VIII
700 DCC 70 LXX 7 VII
600 DC 60 LX 6 VI
500 D 50 L 5 V
400 CD 40 XL 4 IV
3000 MMM 300 CCC 30 XXX 3 III
2000 MM 200 CC 20 XX 2 II
1000 M 100 C 10 X 1 I
私たちは、彼らの間の対応は、4つのグループに分けすることができます:
最初のグループは、最上位ビットが4未満であり、例えば、それらが重畳され、ローマ、に対応する番号を、1000 Mは、3000です
MMM
。第2のグループは、最上位ビットは、ローマ数字1で始まり、2つの隣接する最初のいくつかのローマ関係と共にローマ初め5にその数に対応する、4に等しいです。
ローマの番号に対応する第3のグループ、5-8間の最高レベルは、ローマの番号の先頭に追いつくためにオーバーレイに基づいていますロマン数5の始まりである、それはまた、両者の関係に隣接しています。
第四のグループ、9への最大等しいが、数に代わって1000において、例えば900のために、1から始まるローマローマ組成に対応する間隔の数であり、
M
前者プラス代表100C
、すなわち、CM
中間間隔の両方、。
上記対応関係、我々異なる整数、ハイからローへのローマ数字配列の初期化文字列の組み合わせは、順次ローマの数を算出します。
public String intToRoman(int num) {
String[] roman = {"M", "D", "C", "L", "X", "V", "I"};
int[] value = {1000, 500, 100, 50, 10, 5, 1};
StringBuilder sb = new StringBuilder();
for (int i=0; i<value.length; i+=2) {
// 得到当前num的最高位
int tem = num/value[i];
if (tem < 4) {
// 叠加
for (int j=0; j<tem; j++) {
sb.append(roman[i]);
}
} else if (tem == 4) {
// 相邻
sb.append(roman[i]+roman[i-1]);
} else if (tem > 4 && tem < 9) {
// 相邻
sb.append(roman[i-1]);
for (int j=6; j<=tem; j++) {
sb.append(roman[i]);
}
} else if (tem == 9) {
// 间隔两位
sb.append(roman[i]+roman[i-2]);
}
// 去掉已经参与计算的高位
num = num%value[i];
}
return sb.toString();
}
03第二の溶液
第一の溶液に基づいて、我々は、開始6~9増加アレイの最初の要素に対応して4になります。依然としてローからハイに計算され、利用される第一のモジュロ溶液、異なる丸めされた電流値を差し引いたまま値NUM未満になるまで、この溶液は、減算サイクルで、減少させる必要があります数に。
public String intToRoman2(int num) {
String[] roman = {"M", "CM", "D", "CD", "C", "XC",
"L", "XL", "X", "IX", "V", "IV", "I"};
int[] value = {1000, 900, 500, 400, 100, 90,
50, 40, 10, 9, 5, 4, 1};
StringBuilder sb = new StringBuilder();
for (int i=0; i<value.length; i++) {
while (num >= value[i]) {
sb.append(roman[i]);
num -= value[i];
}
}
return sb.toString();
}
04第三の溶液
トリッキーな解決策もあります。トピックはNUMの範囲を限定するため、最大値が4000を超えない、我々は、4つの部分、百に対応する、3、2、(numは3桁の数である)0、千4つのみ可能に分割numにすることができそこ9可能10、0であり、10ビットが可能10であり、それらは唯一の順次列に対応するNUM異なるビットを取る必要が記載されています。
このソリューションの時間の複雑さがありますO(1)
。
public static String intToRoman3(int num) {
String M[] = {"", "M", "MM", "MMM"};
String C[] = {"", "C", "CC", "CCC", "CD",
"D", "DC", "DCC", "DCCC", "CM"};
String X[] = {"", "X", "XX", "XXX", "XL",
"L", "LX", "LXX", "LXXX", "XC"};
String I[] = {"", "I", "II", "III", "IV",
"V", "VI", "VII", "VIII", "IX"};
return M[num/1000] + C[(num%1000)/100] +
X[(num%100)/10] + I[num%10];
}
05まとめ
テーマ別アルゴリズムが連続してい半年以上日間、特集記事のアルゴリズム219件の +記事、公衆番号]ダイアログボックスの返信[ データ構造とアルゴリズム ]、[ アルゴリズム ]、[ データ構造 ]のいずれかの記事のコレクションのシリーズを取得するキーワード。
それは、すべてだあなたは何か良い解決策のアイデア、提案やその他の問題がある場合、あなたは以下のコメントを交換することができ、親指、メッセージ転送およびサポートは、私にとっての最大の報酬です!