根据题目要求,必须是32位有符号整数,数值范围是[-2^31, 2^31-1],换算出来就是-2147483648 —— 2147483647之间。将此范围内的数值反转可能会导致溢出,比如1234567893,反转之后为3987654321,已然超出了以上范围。因此,先找出溢出条件,将其排除。

对一个整数x,x%10可以获得x最后一位数字mod,也就是要获得的反转数值的首位数字。我们设reverse为反转后的数值变量,则reverse = reverse * 10 + mod,reverse初始值设为0.

  1. 当reverse > 0时:

    • 当reverse > INT_MAX/10时,reverse * 10 + mod必然溢出,此时应返回0.
    • 当reverse == INT_MAX/10并且mod > 7时,reverse * 10 + mod必然溢出,此时也返回0.
  2. 当reverse < 0时:

    • 当reverse < INT_MAX/10时,reverse * 10 + mod必然溢出,此时应返回0.
    • 当reverse == INT_MAX/10并且mod < -8时,reverse * 10 + mod必然溢出,此时也返回0.

循环对x%10取值,直到x为0时,反转已然完成,需要退出循环,因此,循环进行的条件为x != 0。

#include <stdio.h>
#include <stdlib.h>

int reverse(int x)
{
  int mod = 0;
  int reverse = 0;
  while (x != 0)
  {
    mod = x % 10;
    x = x / 10;
    // 当x为正值时,reverse必是正值,则当
    // 当reverse > INT_MAX/10时,reverse*10 + mod 必然大于INT_MAX,必然溢出
    // 当reverse == INT_MAX/10时,reverse*10 + mod要大于INT_MAX(即溢出),则mod必须大于7
    if (reverse > INT_MAX / 10 || reverse == INT_MAX / 10 && mod > 7)
    {
      return 0;
    }
    // 同理,当x为负值时,reverse为负值,则当
    // reverse < INT_MIN / 10时,reverse必然溢出
    // reverse == INT_MIN / 10 && mod < -8,reverse溢出
    if (reverse < INT_MIN / 10 || reverse == INT_MIN / 10 && mod < -8)
    {
      return 0;
    }
    reverse = reverse * 10 + mod;
  }
  return reverse;
}

int main (void) {
  int x = 178237;
  int y = -23682;
  printf("%d %d %d %d", reverse(x), reverse(y), reverse(1234567894), reverse(-1234567894));
  return 0;
}
执行用时:4 ms, 在所有 C 提交中击败了66.25%的用户
内存消耗:5.6 MB, 在所有 C 提交中击败了34.16%的用户

阿料
1 声望4 粉丝

一个平凡的coder