回文数
给你一个整数 x
,如果 x
是一个回文整数,返回 true
;否则,返回 false
。
回文数
是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
- 例如,
121
是回文,而123
不是。
示例 1:
输入:x = 121
输出:true
示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。
提示:
-231 <= x <= 231 - 1
进阶:你能不将整数转为字符串来解决这个问题吗?
class Solution {
public boolean isPalindrome(int x) {
if(x<0){
return false;
}
int cur=0,num=x;
while(num>0){
cur=10*cur+num%10;
num/=10;
}
return cur==x;
}
}
加一
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
示例 2:
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。
示例 3:
输入:digits = [9]
输出:[1,0]
解释:输入数组表示数字 9。
加 1 得到了 9 + 1 = 10。
因此,结果应该是 [1,0]。
提示:
1 <= digits.length <= 100
0 <= digits[i] <= 9
class Solution {
public int[] plusOne(int[] digits) {
int carry = 1;
for (int i = digits.length - 1; i >= 0; i--) {
carry = carry + digits[i];
digits[i] = carry % 10;
carry = carry / 10;
}
if (carry > 0) {
digits = new int[digits.length + 1];
digits[0] = 1;
}
return digits;
}
}
- 初始化进位:首先,方法通过
int carry = 1;
初始化一个进位变量carry
,值为1,因为我们想要给原数加1。 - 从最低位开始处理:使用一个
for
循环从数组的最后一个元素(即最低位数字)开始向前遍历。在每次迭代中,将当前位的值(digits[i]
)与进位carry
相加。 - 更新当前位和进位:相加的结果对10取模(
carry % 10
),得到的结果是当前位的值(因为每一位的最大值为9,加1后最多变成10,需要进位),然后将这个值重新赋给digits[i]
。同时,更新进位值,即相加的结果除以10(carry / 10
),因为每进位一次,意味着增加了10的倍数。 - 处理最高位进位:如果循环结束后,进位
carry
仍然大于0,说明原数的最高位也产生了进位,需要在数组的最前面增加一个新的元素来存储这个进位值(在这里是1)。因此,创建一个新的数组,长度比原数组多1,并将新数组的第一个元素设置为1。 - 返回结果:最后,返回处理后的数组,它表示了原数加1后的结果。
其中,原数组扩容:
- 创建新数组:
digits = new int[digits.length + 1];
这行代码创建了一个长度比原数组多1的新数组。 - 设置进位值:
digits[0] = 1;
这行代码将新数组的第一个元素设置为1,表示进位。 - 其余元素默认为0:由于新数组的长度比原数组多1,且没有显式地设置新数组的其他元素,因此这些元素将保持Java默认的int类型初始值,即0。
172. 阶乘后的零
给定一个整数 n
,返回 n!
结果中尾随零的数量。
提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1
示例 1:
输入:n = 3
输出:0
解释:3! = 6 ,不含尾随 0
示例 2:
输入:n = 5
输出:1
解释:5! = 120 ,有一个尾随 0
示例 3:
输入:n = 0
输出:0
提示:
0 <= n <= 104
进阶:你可以设计并实现对数时间复杂度的算法来解决此问题吗?
class Solution {
public int trailingZeroes(int n) {
int count = 0;
while (n > 0) {
n /= 5; // 每次除以5,找到所有能被5整除的数,以及能被25、125等整除的数
count += n; // 累加这些数,因为每个数都至少贡献一个5的因子
}
return count;
}
}
69. x 的平方根
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
示例 1:
输入:x = 4
输出:2
示例 2:
输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
提示:
0 <= x <= 231 - 1
class Solution {
public int mySqrt(int a) {
long x = a;
while (x * x > a) x = (x + a / x) / 2;
return (int)x;
}
}
- 初始化:方法首先通过
long x = a;
将输入的整数a
转换为long
类型的变量x
。这是因为当a
较大时,a
的平方可能会超过int
类型的最大值,导致溢出。使用long
类型可以避免这个问题。 - 牛顿迭代法:接下来,方法进入一个
while
循环,循环条件是x * x > a
。这意味着只要当前近似值x
的平方大于目标值a
,循环就会继续。在每次迭代中,都会使用牛顿迭代法的公式来更新x
的值:x = (x + a / x) / 2
。这个公式是牛顿法求解f(x) = x^2 - a = 0
的根的迭代公式,其中f'(x) = 2x
是f(x)
的导数。然而,在这个实现中,为了避免在每次迭代中计算导数,我们使用了a / x
来近似f'(x)
的倒数(在x
接近平方根时,这是一个合理的近似),并且直接更新了x
的值。 - 类型转换和返回:最后,当
x
的平方不再大于a
时(注意,由于浮点数的精度问题,x * x
可能永远不会完全等于a
,但会足够接近以至于满足循环条件),方法通过return (int)x;
将x
转换回int
类型并返回。由于我们是从一个较大的值开始迭代并逐渐逼近平方根,因此这个转换会向下取整到最接近的整数。