LeetCode12、整数からローマ数字

タイトル説明;

  1. 整数からローマ数字へ
    ローマ数字には、I、V、X、L、C、D、Mの7文字が含まれています。

文字値
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
たとえば、ローマ数字2はIIと表記され、2つの平行1を意味します。12はXIIと表記され、X + IIを意味します。27はXXVII、つまりXX + V + IIと表記されます。

通常、ローマ数字の小さい数字は大きい数字の右側にあります。ただし、特殊なケースがあります。たとえば、4はIIIIではなくIVと表記されます。数1は数5の左側にあり、表される数は、数5から数1を引いた数4に等しくなります。同様に、数字9はIXとして表されます。この特別なルールは、次の6つの状況にのみ適用されます。

V(5)とX(10)の左側に配置して、4と9を表すことができます。
XはL(50)とC(100)の左側に配置して、40と90を表すことができます。
Cは、D(500)とM(1000)の左側に配置して、400と900を表すことができます。
整数を指定して、ローマ数字に変換します。入力が1から3999の範囲であることを確認してください。

例1:

入力:3
出力: "III"
例2:

入力:4
出力: "IV"
例3:

入力:9
出力: "IX"
例4:

入力:58
出力: "LVIII"
説明:L = 50、V = 5、III = 3
例5:

入力:1994
出力: "MCMXCIV"
説明:M = 1000、CM = 900、XC = 90、IV =4。
合格112,416提出済み174,910

直接思考法(1回AC)

class Solution {
    
    
    public String intToRoman(int num) {
    
    
        StringBuilder string = new StringBuilder();
        
        if(num<1||num>3999){
    
    
            return string.toString();
        }
        int[] nums = new int[4];
        nums[0]=num%10;//个位
        nums[1]=num/10%10;//十位
        nums[2] = num/100%10;//百位
        nums[3] = num/1000%10;//千位
        // System.out.println(nums[2]);
        String[] encode = new String[]{
    
    "I","V","X","L","C","D","M"};
        int i=3;
        while(i>=0){
    
    
            if(i==3){
    
    //千位是特俗的,它有一个范围要求。
                for(int j=0;j<nums[3];j++)
                    string.append("M");
                i--;
            }
          else{
    
    
               if(nums[i]==9){
    
    
                   string.append(encode[2*i]);
                   string.append(encode[2*i+2]);
                   i--;
                   continue;
               }
              else if(nums[i]>=5){
    
    
                  string.append(encode[2*i+1]);//一半
                 
                   for(int j=0;j<nums[i]-5;j++)
                    string.append(encode[2*i]);
                i--;
                continue;
              }
              else if(nums[i]==4){
    
    
                    string.append(encode[2*i]);
                    string.append(encode[2*i+1]);
                    i--;
                    continue;
              }else{
    
    
                   for(int j=0;j<nums[i];j++)
                    string.append(encode[2*i]);
                i--;
                continue;
              }

          }     

        }
        return string.toString();

        

    }
}

ここに画像の説明を挿入
複雑さの分析:
時間の複雑さ:iは定数なので、論理的にはO(n)ですが、nums [i]の値は0〜9の間のみです。したがって、最悪の複雑さも定数クラスO(1)であると考えることができます。
スペースの複雑さ:O(1)

以下では、コード構文を最適化します

 public String intToRoman(int num) {
    
    
            StringBuilder string = new StringBuilder();

            if(num<1||num>3999){
    
    
                return string.toString();
            }
            int[] nums = new int[4];
            nums[0]=num%10;//个位
            nums[1]=num/10%10;//十位
            nums[2] = num/100%10;//百位
            nums[3] = num/1000%10;//千位
            //适合任意有意义位数的整数化为罗马
            // System.out.println(nums[2]);
            String[] encode = new String[]{
    
    "I","V","X","L","C","D","M"};
            int i=3;
            while(i>=0){
    
    
                if(i==3){
    
    //千位是特俗的,它有一个范围要求。
                    string.append("M".repeat(nums[3]));
                    i--;
                }
                else{
    
    
                    if(nums[i]==9){
    
    
                        string.append(encode[2*i]);
                        string.append(encode[2*i+2]);
                        i--;
                    }
                    else if(nums[i]>=5){
    
    
                        string.append(encode[2*i+1]);//一半

                        string.append(encode[2 * i].repeat(Math.max(0, nums[i] - 5)));
                        i--;
                    }
                    else if(nums[i]==4){
    
    
                        string.append(encode[2*i]);
                        string.append(encode[2*i+1]);
                        i--;
                    }else{
    
    
                        string.append(encode[2 * i].repeat(Math.max(0, nums[i])));
                        i--;
                    }

                }

            }
            return string.toString();
        }

ここに画像の説明を挿入

公式ソリューション

1.貪欲なアルゴリズム

実際、私はそれを見て、貪欲なアルゴリズムが使用されていることを知っていました。なぜなら、毎回最大値を使用してエンコードしたからです。左から順に、可能な最大の記号を使用する必要があることを示します。したがって、貪欲なアルゴリズムを使用することは理にかなっています。貪欲アルゴリズムは、現時点で最良の決定を行うアルゴリズムであり、この場合、最も可能性のあるシンボルを使用します。

int[] values = {
    
    1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};    
String[] symbols = {
    
    "M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};

public String intToRoman(int num) {
    
    
    StringBuilder sb = new StringBuilder();
    // Loop through each symbol, stopping if num becomes 0.
    for (int i = 0; i < values.length && num >= 0; i++) {
    
    
        // Repeat while the current symbol still fits into num.
        while (values[i] <= num) {
    
    
            num -= values[i];
            sb.append(symbols[i]);
        }
    }
    return sb.toString();
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/integer-to-roman/solution/zheng-shu-zhuan-luo-ma-shu-zi-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2:ハードコードされた数値

public String intToRoman(int num) {
    
    
    
    String[] thousands = {
    
    "", "M", "MM", "MMM"};
    String[] hundreds = {
    
    "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; 
    String[] tens = {
    
    "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
    String[] ones = {
    
    "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
    
    return thousands[num / 1000] + hundreds[num % 1000 / 100] + tens[num % 100 / 10] + ones[num % 10];
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/integer-to-roman/solution/zheng-shu-zhuan-luo-ma-shu-zi-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

おすすめ

転載: blog.csdn.net/qq_44861675/article/details/108424686