LeetCode - 13. Roman to Integer | Lacerta

13. Roman to Integer

题目

problem

题意分析

本题是要将罗马数字转换成对应的整数。

本题考点

解法I - 直接相加

我们依次遍历字母,记下上一次的字母的值,若上一次的字母的值比本次字母小,则做减法,否则做加法。

注意,因为在上一轮我们已经加过一次上一次的值了,做减法的时候需要减去两倍的上一次的值把上一次的值给扣除。

实现
class Solution {
  public int romanToInt(String s) {
    int sum = 0;

    // 上一次的字母
    Character last = null;

    for (int i = 0; i < s.length(); i++) {
      Character c = s.charAt(i);
      
      int currentValue = getRomanValue(c);
      int lastValue = getRomanValue(last);
      
      // 如果本次的值大于上次的值,说明我们要做减法
      // 在这里需要把上一次添加的值给减去
      if (currentValue > lastValue) {
        sum = sum - 2 * lastValue + currentValue;
      } else {
        // 如果本次的值小于等于上次的值,则直接相加
        sum += currentValue;
      }

      // 更新上一次的值
      last = c;
    }

    return sum;
  }

  private int getRomanValue(Character c) {
    if (c == null) return Integer.MAX_VALUE;
    switch(c) {
      case 'I':
      return 1;
      case 'V':
      return 5;
      case 'X':
      return 10;
      case 'L':
      return 50;
      case 'C':
      return 100;
      case 'D':
      return 500;
      case 'M':
      return 1000;
      default:
      return 0;
    }
  }
}

解法II - 优化

在解法I中,我们在遇到减法时,每次都需要减去2倍的上一次的值,多做了一次加法。

我们这次将通过判断,直接进行相加(减),减少一步加法操作。

实现
class Solution {
  public int romanToInt(String s) {
    // 初始值为最后一个字母的值
    // 因为下面的循环无法覆盖到最后一个字母
    int sum = getRomanValue(s.charAt(s.length() - 1));

    // 注意边界条件i < s.length() - 1,防止越界
    for(int i = 0; i < s.length() - 1; i ++) {
      // 我们每次取两个字母进行判断
      Character currentLetter = s.charAt(i);
      Character nextLetter = s.charAt(i + 1);
      
      int currentValue = getRomanValue(currentLetter);
      int nextValue = getRomanValue(nextLetter);
      
      if (currentValue >= nextValue) {
        sum += currentValue;
      } else {
        sum -= currentValue;
      }
    }

    return sum;
  }

  private int getRomanValue(Character c) {
    if (c == null) return Integer.MAX_VALUE;
    switch(c) {
      case 'I':
      return 1;
      case 'V':
      return 5;
      case 'X':
      return 10;
      case 'L':
      return 50;
      case 'C':
      return 100;
      case 'D':
      return 500;
      case 'M':
      return 1000;
      default:
      return 0;
    }
  }
}