LeetCodeOJ刷題之13【Roman to Integer】

Roman to Integer

Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
意思就是:
給出一個羅馬數字,返回其對應的整數 num( 0<=num<=3999)表示;
羅馬數字範圍從 0-->3999
羅馬數字有:git

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

Solutions

  • 1 Roman to Integer -- 59ms
    • 這種方法是對羅馬數字從頭至尾的掃描一遍。分析一下能夠知道,只有 49 纔會出現小一點的羅馬數字出如今大的羅馬數字的前面!好比:CD=400 其中 C=100 , D=500 ,此時須要的後一個羅馬數字減去前面一個羅馬數字,其餘狀況都是一直加的。代碼以下:
    class Solution {
    public:
        int romanToInt(string s) {
            int idx=0,n=s.length();
            if(s.length()<=0)return 0;
    
            string roman="IVXLCDM";
            int  nums[] ={1,5,10,50,100,500,1000};
            int  res=0;
            //idx=roman.find(s.at(0));
            //if(idx<0||idx>6)return 0;
            //if(n==1){
                //return nums[idx];
            //}
            int num1,num2;
            idx=0;
            while(idx<n-1){ // 須要考慮 idx+1 的越界狀況
                num1=roman.find(s[idx]);
                num2=roman.find(s[idx+1]);
                if(num2>num1){
                    res=res+(nums[num2]-nums[num1]);
                    idx+=2;
                }else{
                    res=res+nums[num1];
                    ++idx;
                }
            }
            if(n-1==idx){ //須要考慮可能剩下的最後一個羅馬數字
                num1=roman.find(s[n-1]);
                res+=nums[num1];
            }
            return res;
        }
    };
  • 2 Roman to Integer -- 49ms
    • 方案1中須要考慮 idx+1 的越界狀況,因此還要在最後再增長一個判斷,且使用的是從前向後掃描羅馬數字字串;那若是是從後向前掃描羅馬數字字串呢?思想會不會簡單一點呢?分析一下能夠看出,從後向前掃描,能夠一直加下去,除了一種狀況:當前掃描的數小於上一個掃描的數!也就是說只有這一個條件了,不須要再判斷什麼越不越界的問題了。如:MCMVI=1906 , 掃描 VV>I(在羅馬數字中,如下同),因此直接加,結果爲:6,掃描 M 也同樣,結果爲1006,接下來掃描到 C ,此時 C<M ,因此應是減去 C ,結果是906,最後再加 M ,獲得結果:1906。要作的,只是記錄下上一次的羅馬數字。代碼以下:
    class Solution {
    public:
        int romanToInt(string s) {
            if(s.length()<=0)return 0;
            string roman="IVXLCDM";
            int  nums[] ={1,5,10,50,100,500,1000};
            int  n=s.length();
            int  res=0, idx=n-1, pre=0, ndx;
            while(idx>=0){
                ndx=roman.find(s[idx]);
                if(pre>ndx){
                    res-=nums[ndx];
                }else{
                    res+=nums[ndx];
                }
                pre=ndx;
                --idx;
            }
            return res;
        }
    };
  • 3 Roman to Integer -- 53ms
    • 查閱了網友的解答,發現這一個方式挺好的,思路也很簡單:
      • 逐個遍歷羅馬數字串,根據當前遍歷到的字符,進行對應的累加操做。
      • 羅馬數字共 7 個符號,IVXLCDM ,若是遍歷到羅馬數字 w ,則判斷以前已經求出的數字 res 是否小於 w ,若是小於,則 加上 w :res=res+w,不然減去 w 。緣由是:由於是從後向前遍歷,因此咱們已經遍歷出來的數字確定是會小於下一進位的數字的,好比 189 ,89再大,也沒有100大!因此此算法使用的就是這種思想,一旦出現違法了這種狀況,那就是出現了 4 或者 9 的狀況。說明咱們加多了,那就要減去。說的可能比較很差徹底理解,看代碼:
      class Solution {
      public:
      int romanToInt(string s) {
          int res = 0 ,n=s.length();
          for (int i = n - 1; i >= 0; --i) {
              char c = s.at(i);
              switch (c) {
              case 'I':
                  res += (res >= 5 ? -1 : 1);
                  break;
              case 'V':
                  res += 5;
                  break;
              case 'X':
                  res += 10 * (res >= 50 ? -1 : 1);
                  break;
              case 'L':
                  res += 50;
                  break;
              case 'C':
                  res += 100 * (res >= 500 ? -1 : 1);
                  break;
              case 'D':
                  res += 500;
                  break;
              case 'M':
                  res += 1000;
                  break;
              }
          }
          return res;
      }
      };
  • 看了一下其餘的代碼,大體的思想都是上面的方法,可能還有我沒發現的。只是代碼編寫的形式不一樣而已。

附錄

同系列:LeetCodesOJhttp://www.cnblogs.com/lomper/tag/LeetCodesOJ/github

相關文章
相關標籤/搜索