diff --git a/leet-code/8-string-to-integer/README.md b/leet-code/8-string-to-integer/README.md index 5a3693c..df95300 100644 --- a/leet-code/8-string-to-integer/README.md +++ b/leet-code/8-string-to-integer/README.md @@ -1,87 +1,89 @@ # 8-string-to-integer -Implement the myAtoi(string s) function, which converts a string to a 32-bit signed integer. +Implement the `myAtoi(string s)` function, which converts a string to a 32-bit signed integer. -The algorithm for myAtoi(string s) is as follows: +The algorithm for `myAtoi(string s)` is as follows: -Whitespace: Ignore any leading whitespace (" "). -Signedness: Determine the sign by checking if the next character is '-' or '+', assuming positivity if neither present. -Conversion: Read the integer by skipping leading zeros until a non-digit character is encountered or the end of the string is reached. If no digits were read, then the result is 0. -Rounding: If the integer is out of the 32-bit signed integer range [-231, 231 - 1], then round the integer to remain in the range. Specifically, integers less than -231 should be rounded to -231, and integers greater than 231 - 1 should be rounded to 231 - 1. -Return the integer as the final result. +1. **Whitespace**: Ignore any leading whitespace (`" "`). +2. **Signedness**: Determine the sign by checking if the next character is `'-'` or `'+'`, assuming positivity if neither present. +3. **Conversion**: Read the integer by skipping leading zeros until a non-digit character is encountered or the end of the string is reached. If no digits were read, then the result is 0. +4. **Rounding**: If the integer is out of the 32-bit signed integer range `[-2^31, 2^31 - 1]`, then round the integer to remain in the range. Specifically, integers less than `-2^31` should be rounded to `-2^31`, and integers greater than `2^31 - 1` should be rounded to `2^31 - 1`. +5. **Return** the integer as the final result. - +--- -Example 1: +### Example 1: -Input: s = "42" +**Input**: `s = "42"` +**Output**: `42` -Output: 42 +**Explanation**: +The underlined characters are what is read in and the caret is the current reader position. +Step 1: `"42"` (no characters read because there is no leading whitespace) + `^` +Step 2: `"42"` (no characters read because there is neither a `'-'` nor `'+'`) + `^` +Step 3: `"42"` (`"42"` is read in) + `^` -Explanation: +--- -The underlined characters are what is read in and the caret is the current reader position. -Step 1: "42" (no characters read because there is no leading whitespace) - ^ -Step 2: "42" (no characters read because there is neither a '-' nor '+') - ^ -Step 3: "42" ("42" is read in) - ^ -Example 2: +### Example 2: -Input: s = " -042" +**Input**: `s = " -042"` +**Output**: `-42` -Output: -42 +**Explanation**: +Step 1: `" -042"` (leading whitespace is read and ignored) + `^` +Step 2: `" -042"` (`'-'` is read, so the result should be negative) + `^` +Step 3: `" -042"` (`"042"` is read in, leading zeros ignored in the result) + `^` -Explanation: +--- -Step 1: " -042" (leading whitespace is read and ignored) - ^ -Step 2: " -042" ('-' is read, so the result should be negative) - ^ -Step 3: " -042" ("042" is read in, leading zeros ignored in the result) - ^ -Example 3: +### Example 3: -Input: s = "1337c0d3" +**Input**: `s = "1337c0d3"` +**Output**: `1337` -Output: 1337 +**Explanation**: +Step 1: `"1337c0d3"` (no characters read because there is no leading whitespace) + `^` +Step 2: `"1337c0d3"` (no characters read because there is neither a `'-'` nor `'+'`) + `^` +Step 3: `"1337c0d3"` (`"1337"` is read in; reading stops because the next character is a non-digit) + `^` -Explanation: +--- -Step 1: "1337c0d3" (no characters read because there is no leading whitespace) - ^ -Step 2: "1337c0d3" (no characters read because there is neither a '-' nor '+') - ^ -Step 3: "1337c0d3" ("1337" is read in; reading stops because the next character is a non-digit) - ^ -Example 4: +### Example 4: -Input: s = "0-1" +**Input**: `s = "0-1"` +**Output**: `0` -Output: 0 +**Explanation**: +Step 1: `"0-1"` (no characters read because there is no leading whitespace) + `^` +Step 2: `"0-1"` (no characters read because there is neither a `'-'` nor `'+'`) + `^` +Step 3: `"0-1"` (`"0"` is read in; reading stops because the next character is a non-digit) + `^` -Explanation: +--- -Step 1: "0-1" (no characters read because there is no leading whitespace) - ^ -Step 2: "0-1" (no characters read because there is neither a '-' nor '+') - ^ -Step 3: "0-1" ("0" is read in; reading stops because the next character is a non-digit) - ^ -Example 5: +### Example 5: -Input: s = "words and 987" +**Input**: `s = "words and 987"` +**Output**: `0` -Output: 0 +**Explanation**: +Reading stops at the first non-digit character `'w'`. -Explanation: +--- -Reading stops at the first non-digit character 'w'. +### Constraints: - - -Constraints: - -0 <= s.length <= 200 -s consists of English letters (lower-case and upper-case), digits (0-9), ' ', '+', '-', and '.'. \ No newline at end of file +- `0 <= s.length <= 200` +- `s` consists of English letters (lower-case and upper-case), digits (`0-9`), `' '`, `'+'`, `'-'`, and `'.'`. diff --git a/leet-code/8-string-to-integer/index.js b/leet-code/8-string-to-integer/index.js index 325c133..b019483 100644 --- a/leet-code/8-string-to-integer/index.js +++ b/leet-code/8-string-to-integer/index.js @@ -3,34 +3,41 @@ * @return {number} */ var myAtoi = function(s) { - const originalLength = s.length - let digits = ""; - let hasStarted = false; - let sign = 1; - for (var i = 0; i < originalLength; i++) { - const char = s.charAt(i) - console.log(char) - if (char === '-' && !hasStarted) { - sign = -1 - } - else if (!/\D/.test(char)) { - hasStarted = true; - digits += char; - } - else if (char === " " && !hasStarted) { - continue; - } - else if (hasStarted) { - break; - } else { - return 0 - } - } + // edge case - the string is empty + if (!s) return 0 + // start index at the beginning of the string + let i = 0; + // end index is the last character of the string + let n = s.length; + // trim leading whitespace + while (i < n && s.charAt(i) === ' ') { i++ } + // edge case - the string contained only whitespace + if (i === n) return 0; + // store the sign of the number, e.g. positive or negative + let sign = 1; + if (s.charAt(i) === '+') { i++ } + else if (s.charAt(i) === '-') { sign = -1; i++ } - let result = 0 - let length = digits.length - 1; - for (var i = length; i >= 0; i--) { - result += Math.pow(10, length-i) * parseInt(digits.charAt(i)) - } - return sign * result -}; \ No newline at end of file + // shift bits to quickly calcualte the min and max 32 bit signed int + // smallest 32 bit signed int + const min = -(2**31) + // largest 32 bit signed int + const max = 2**31 -1 + // sum of digits + let number = 0; + // consider characters until they are not numeric digits + while (i < n && s.charAt(i) <= '9' && s.charAt(i) >= '0') { + // get the numeric value of the character + const digit = parseInt(s.charAt(i)) + // shift the total by a significant digit and add the value of the next digit + number = number * 10 + digit + // short curcuit if the sum exceeds the range of a 32 bit signed int + const value = sign * number; + if (value <= min)return min + if (value >= max) return max; + // consider the next character + i++; + } + // apply the sign (positive or negative) + return sign * number +} \ No newline at end of file