跳轉到

13. Roman to Integer

題目大意

羅馬數字由七個不同的符號表示:IVXLCDM

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

例如,2 用羅馬數字寫作 II,就是兩個一加在一起。12 寫作 XII,即 X + II。數字 27 寫作 XXVII,即 XX + V + II

羅馬數字通常從左至右按大小寫成。然而,數字四不寫作 IIII。相反,數字四寫作 IV。因為一在五前面,我們把它減去,這樣就變成了四。同樣的原則也適用於數字九,寫作 IX。有六種情況會使用減法原則:

  • I 可以放在 V(5)和 X(10)之前,來表示 4 和 9。
  • X 可以放在 L(50)和 C(100)之前,來表示 40 和 90。
  • C 可以放在 D(500)和 M(1000)之前,來表示 400 和 900。

給出一個羅馬數字,將其轉換為一個整數。

範例一
Input: s = "III"
Output: 3
Explanation: III = 3.
範例二
Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.
範例三
Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

題目原文連結

約束條件

  • 1 <= s.length <= 15
  • s 僅包含字符  ('I', 'V', 'X', 'L', 'C', 'D', 'M').
  • 保證 s 是範圍在 [1, 3999] 內的有效羅馬數字。

我的答案

第一次解法
<?php
class Solution {

    /**
     * 將羅馬數字轉換為整數。
     *
     * @param String $s 羅馬數字字串
     * @return Integer 轉換後的整數
     */
    function romanToInt($s) {
        // 將字串分割成單個字元的陣列
        $s = str_split($s,1);
        // 初始化佇列,用於臨時儲存字元,主要處理減法規則
        $q = [];
        // 初始化總數為0
        $total = 0;
        // 羅馬數字與整數的對映關係,包括減法規則的特殊情況
        $map = [
          "I" => 1,
          "V" => 5,
          "X" => 10,
          "L" => 50,
          "C" => 100,
          "D" => 500,
          "M" => 1000,
          "IV" => 4,
          "IX" => 9,
          "XL" => 40,
          "XC" => 90,
          "CD" => 400,
          "CM" => 900
        ];

        // 遍歷每個字元
        foreach($s as $v){
          // 檢查佇列長度
          $len = count($q);
          // 如果佇列為空
          if($len == 0){
              // 檢查當前字元是否是減法規則的候選(C, I, X)
              if ($v == "C" || $v== "I" || $v == "X") {
                   $q[] = $v; // 將其加入佇列等待下一個字元
              } 
              // 將當前字元代表的數值加到總數中
              $total += $map[$v];
          } else {
              // 構造可能的減法規則字串
              $spec = $q[0].$v;
              // 如果構造的字串在對映中存在,表示遇到了減法規則
              if(isset($map[$spec])){
                  // 根據減法規則調整總數,並清空佇列
                  $total += ($map[$spec] - $map[$q[0]]);
                  $q = [];
              } else {
                  // 如果不是減法規則,則直接加上當前字元代表的數值
                  // 並更新佇列為當前字元,準備下一輪檢查
                  $total += ($map[$v]);
                  $q[0] = $v;
              }

          }
        }
        // 返回計算出的總數
        return $total;
    }
}

我寫的程式碼似乎有點太長了...


參考LeetCode討論區別人邏輯改寫
<?php
class Solution {

    /**
     * @param String $s
     * @return Integer
     */
    function romanToInt($s) {
        // 初始化總數為0
        $total = 0;
        // 初始化前一個值為0,用於比較當前字元表示的值是否小於前一個字元的值
        $prevValue = 0;
        // 羅馬數字與整數的對映關係
        $map = [
            "I" => 1,
            "V" => 5,
            "X" => 10,
            "L" => 50,
            "C" => 100,
            "D" => 500,
            "M" => 1000,
        ];

        // 從字串的最後一個字元開始向前遍歷
        for ($i = strlen($s) - 1; $i >= 0; $i--) {
            // 獲取當前字元代表的整數值
            $value = $map[$s[$i]];

            // 如果當前值小於前一個值,說明遇到了特殊的減法規則(如IV、IX等)
            if ($value < $prevValue) {
                // 根據減法規則,從總數中減去當前值
                $total -= $value;
            } else {
                // 如果當前值不小於前一個值,直接加到總數中
                $total += $value;
            }

            // 更新前一個值為當前值,為下一次迴圈做準備
            $prevValue = $value;
        }

        // 返回最終計算出的整數
        return $total;
    }
}