LeetCode热题(JS版)- 8. 字符串转换整数

87 阅读3分钟

题目

实现C/C++中的atoi函数myAtoi(string s),将字符串转换为一个32位有符号整数。

算法myAtoi(string s)描述如下:

  1. 读取并忽略开头的空格。
  2. 检查下一个字符(不在最后)是'-' 或 '+'。如果是,请将此字符读入。这决定最终结果是负还是正。如果两者都不存在,则假设结果为正。
  3. 读取下一个字符,直到到达下一个非数字字符或输入末尾。字符串的其余部分将被忽略。
  4. 将这些数字转换为整数(即"123"->123"0032"->32)。如果未读取任何数字,则整数为“0”。根据需要更改符号(从步骤2开始)。
  5. 如果整数超出32位有符号整数范围[-231, 231^-1],则对整数进行钳位,使其保持在该范围内。具体来说,小于-231的整数应箝位为-231,大于231 - 1的整数应该箝位为231 - 1
  6. 返回整数作为最终结果。

注意:

  • 只有空格字符“”被视为空白字符。

  • 不要忽略除前导空格或数字后字符串的其余部分之外的任何字符。

 

示例 1:

输入: s = "42"
输出: 42
说明:插入符号是当前读取器的位置。
步骤 1: "42" (带下划线的字符是读入的字符,插入符号是当前读取器的位置。)
         ^
步骤 2: "42" (没有字符,因为既没有'-'也没有'+')
         ^
步骤 3: "42" ("42" 被读入)
           ^
解析的整数是42。

由于42在[-231, 231^-1]范围内,最终结果为42

示例 2:

输入: s = "   -42"
输出: -42
说明:
步骤 1: "   -42" (读取并忽略前导空格)
            ^
步骤 2: "   -42" (已读取“-”,因此结果应为负值)
             ^
步骤 3: "   -42" ("42" 被读入)
               ^
解析的整数是 -42.
由于-42在[-231, 231^-1]范围内,最终结果为-42。

示例 3:

输入: s = "4193 with words"
输出: 4193
说明:
步骤 1: "4193 with words" (不读取字符,因为没有前导空格)
         ^
步骤 2: "4193 with words" (没有读取字符,因为既没有“-”也没有“+”)
         ^
步骤 3: "4193 with words" (读入“4193”;读取停止,因为下一个字符是非数字)
             ^
解析的整数是 4193.
由于4193在[-231, 231^-1]范围内,最终结果为4193。

思路

  • 记录符号
  • 逐个记录数字
  • 逆序组装
function myAtoi(s: string): number {
  let value = 0;
  let sign = 1;
  const numbers = [];
  let start = false; // 开始检测了,用于标记数字后是字符串需要终止

  for (let i = 0; i < s.length; i++) {
    const char = s[i];
    const val = parseInt(char); // 是否为数字
    if (isNaN(val)) {
      if (start) break; // 数字 + 字符 => 终止

      if (char === ' ') continue;

      if (char === '-') {
        start = true;
        sign = -1;
        continue;
      }

      if (char === '+') {
        start = true;
        sign = 1;
        continue;
      }

      break; // 以非数字开始
    } else {
      if (!start) start = true;
      numbers.push(val);
    }
  }

  value = sign * numbers.reverse().reduce((sum, d, i) => sum + d * Math.pow(10, i), 0);
  if (value < -Math.pow(2, 31)) return -Math.pow(2, 31);
  if (value > Math.pow(2, 31) - 1) return Math.pow(2, 31) - 1;
  return value;
}

image.png