Swift solution, O(n) with comments


  • 0
    M

    Roman numerals involve a look behind of 1 character max (ie. VII, IX, X). We leverage this to finish it in a single pass.

    class Solution {
        func romanToInt(_ s: String) -> Int {
            // create a map to convert characters to values
            let conv = ["M": 1000, "D": 500, "C": 100, "L":50, "X": 10, "V": 5, "I": 1]
            // we need an aggregator
            var aggregator = 0
            // Swift strings are not a sequence, so make one
            var chars = s.characters.map{String($0)}
            for i in 0..<chars.count {
                // always add the converted value, we'll check if we need to adjust
                // the value once we're past the first character
                aggregator += conv[chars[i]]!                
                if i > 0 {
                    // look behind one, if the value is LESS that the current, we
                    // have an IX type situation, so remove the I we added 2 times
                    // to account for having added it blindly, and the need to remove
                    // it from the current value
                    if conv[chars[i-1]]! < conv[chars[i]]! {
                        aggr -= conv[chars[i-1]]! * 2
                    }
                }
            }
            
            // done
            return agg
        }
    }
    

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.