===问:
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
===答:
int32intint32int320
方法一:
执行用时 :0 ms/4 ms, 击败了100.00%/45.50% 的用户
内存消耗 :2.3 MB, 击败了5.56%的用户
本方法先将整数转换为字符串,获得正负符号后开始循环转换位置(和之前字符串转换的题目一样)。转换完成后合并,再变成整数返回。
func reverse2(x int) int {
y := strings.Split(strconv.Itoa(x), "")
i := 0
l := len(y)
if y[0] == "-" {
i = 1
l = l + 1
}
j := l / 2
for ; i < j; i++ {
y[i], y[l-1-i] = y[l-1-i], y[i]
}
z := ""
for _, v := range y {
z += v
}
x, _ = strconv.Atoi(z)
// if判断语句仅针对本题中要求的返回值为32位,不要求的话本if语句可以删除
if x > 2147483647 || x < -2147483648 {
return 0
}
return x
}
方法二:
执行用时 :0 ms/4 ms, 击败了100.00%/45.5% 的用户
内存消耗 :2.2 MB, 击败了74.60%/30.95%的用户
本方法利用了数学的方法,嗯嗯,挺有意思,后面详解,还涉及到一个最大最小值衍生出的知识点。
func reverse3(x int) int {
var y int = 0
for x != 0 {
y = y*10 + x%10
x = x / 10
}
// if判断语句仅针对本题中要求的返回值为32位,不要求的话本if语句可以删除
MAX_INT32 := int(^uint32(0) >> 1)
MIN_INT32 := ^MAX_INT32
//if y > 2147483647 || y < -2147483648 {
if y > MAX_INT32 || y < MIN_INT32 {
return 0
}
return y
}
===解:
只解析方法二中的三个知识点:
一、前后交替
xy
for x != 0 {
y = y*10 + x%10
x = x / 10
}
123
// 第一次循环
y=0*10+123%10=0+3=3
x=123/10=12
// 第二次循环
y=3*10+12%10=30+2=32
x=12/10=1
// 第三次循环
y=32*10+1%10=320+1=321
x=1/10=0
每一次循环需要实现:
xyyxxyx
y = y*10 + x%10
y*10x%10
x = x / 10xx
x / 10xx0
在未来的计算中,可能会经常用到公式一第2条和公式二第1条的思路。
二、int32最大最小值的判断
题目要求不能超出int32的范围,那么最简单做法就是直接判断int32的上下限,即
if y > 2147483647 || y < -2147483648 {
...
}
我们这里扩展一下知识点:
uintint
1. 无符号整型uint,其最小值是0,其二进制表示的所有位都为0,
const UINT_MIN uint = 0
其最大值的二进制表示的所有位都为1,那么,
const UINT_MAX = ^uint(0)
2. 有符号整型int,根据补码,其最大值二进制表示,首位0,其余1,那么,
const INT_MAX = int(^uint(0) >> 1)
根据补码,其最小值二进制表示,首位1,其余0,那么,
const INT_MIN = ^INT_MAX
3. 本例中的语句针对int32,那么:
MAX_INT32 := int(^uint32(0) >> 1)
MIN_INT32 := ^MAX_INT32
if y > MAX_INT32 || y < MIN_INT32 {
return 0
}
intmathfloatmath.Min(float64, float64) float64math.Max(float64, float64) float64int
func Min(x, y int64) int64 {
if x < y {
return x
}
return y
}
三、整数相除的结果
公式二第1条,为什么整数相除得到的商即是我们需要的?
因为在go中,整数相除的商为整数,且商不进行四舍五入,直接去掉小数点后面的数字。
比如:
fmt.Println(125 / 3)
fmt.Println(125 / 3.0)
// 输出:
// 41
// 41.666666666666664
由此可知,如果要让两个整数相除的商得到浮点,则只需要除数或被除数是浮点数即可。具体使用方法参考:《golang整数与小数间的加减乘除》