Skip to content

972. Equal Rational Numbers 👎

  • Time: $O(|\texttt{s}| + |\texttt{t}|)$
  • Space: $O(1)$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
 public:
  bool isRationalEqual(string s, string t) {
    return abs(valueOf(s) - valueOf(t)) < 1e-9;
  }

 private:
  const vector<double> ratios{1.0, 1.0 / 9, 1.0 / 99, 1.0 / 999, 1.0 / 9999};

  double valueOf(const string& s) {
    if (s.find('(') == string::npos)
      return stod(s);

    // Get the indices..
    const int leftParenIndex = s.find_first_of('(');
    const int rightParenIndex = s.find_first_of(')');
    const int dotIndex = s.find_first_of('.');

    // integerAndNonRepeating := <IntegerPart><.><NonRepeatingPart>
    const double integerAndNonRepeating = stod(s.substr(0, leftParenIndex));
    const int nonRepeatingLength = leftParenIndex - dotIndex - 1;

    // repeating := <RepeatingPart>
    const int repeating = stoi(s.substr(leftParenIndex + 1, rightParenIndex));
    const int repeatingLength = rightParenIndex - leftParenIndex - 1;
    return integerAndNonRepeating +
           repeating * pow(0.1, nonRepeatingLength) * ratios[repeatingLength];
  }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
  public boolean isRationalEqual(String s, String t) {
    return Math.abs(valueOf(s) - valueOf(t)) < 1e-9;
  }

  private static double[] ratios = new double[] {1.0, 1.0 / 9, 1.0 / 99, 1.0 / 999, 1.0 / 9999};

  private double valueOf(final String s) {
    if (!s.contains("("))
      return Double.valueOf(s);

    // Get the indices..
    final int leftParenIndex = s.indexOf('(');
    final int rightParenIndex = s.indexOf(')');
    final int dotIndex = s.indexOf('.');

    // integerAndNonRepeating := <IntegerPart><.><NonRepeatingPart>
    final double nonRepeating = Double.valueOf(s.substring(0, leftParenIndex));
    final int nonRepeatingLength = leftParenIndex - dotIndex - 1;

    // repeating := <RepeatingPart>
    final int repeating = Integer.parseInt(s.substring(leftParenIndex + 1, rightParenIndex));
    final int repeatingLength = rightParenIndex - leftParenIndex - 1;
    return nonRepeating + repeating * Math.pow(0.1, nonRepeatingLength) * ratios[repeatingLength];
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution:
  def isRationalEqual(self, s: str, t: str) -> bool:
    ratios = [1, 1 / 9, 1 / 99, 1 / 999, 1 / 9999]

    def valueOf(s: str) -> float:
      if s.find('(') == -1:
        return float(s)

      # Get the indices.
      leftParenIndex = s.find('(')
      rightParenIndex = s.find(')')
      dotIndex = s.find('.')

      # integerAndNonRepeating := <IntegerPart><.><NonRepeatingPart>
      integerAndNonRepeating = float(s[:leftParenIndex])
      nonRepeatingLength = leftParenIndex - dotIndex - 1

      # repeating := <RepeatingPart>
      repeating = int(s[leftParenIndex + 1:rightParenIndex])
      repeatingLength = rightParenIndex - leftParenIndex - 1
      return integerAndNonRepeating + repeating * 0.1**nonRepeatingLength * ratios[repeatingLength]

    return abs(valueOf(s) - valueOf(t)) < 1e-9