前言
主要介绍关于数学的一些题目
这些题目技巧性都比较大,没有什么特殊的数据结构和算法,有时就很简单,没思路时也是挺烦。主打的就是模拟或者看破本质
技巧&经验
1.数字取各个位
开撸
1.lc9 回文数
题目描述:
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例
输入:x = 121 输出:true
输入:x = -121 输出:false
Solution:
首先负数可以排除,直接输出false
然后对于回文,字符串倒是很好处理,所以第一想法是将整数转换为字符串
String s = Integer.toString(x);
因为字符串有索引函数,所以对于回文判断来说比较方便
但如果只是处理整数,就得另辟蹊径。
一个思路就是反转一半的数字,即将一个数字的后半部分反转然后再与前半部分比较。循环终止的条件就是,当原始数字小于或等于反转后的数字时,就代表到一半了(因为原始数字在不断除以10,逐渐变小)。
public static boolean isPalindrome(int x) {
if(x<0) return false;
if(x!=0 && x%10==0) return false;
int revertedNumber=0; //定义反转后的数字
while(revertedNumber< x)
{
int y = x%10; // 求出余数
x = x/10; // 继续整除
revertedNumber = revertedNumber * 10 + y; // 计算反转后的数字
}
return revertedNumber/10==x || revertedNumber==x ;
}
时间复杂度取决于整除10的次数,所以是O(logn),空间复杂度O(1)
2.lc263 丑数
题目描述
丑数 就是只包含质因数 2、3 和 5 的正整数。给你一个整数 n ,请你判断 n 是否为 丑数
示例
输入:n = 6 输出:true
输入:n = 14 输出:false
Solution:
思路就是一直用2,3,5除,(可以先用2整除,除不尽就换3,以此类推)最后看剩下的是不是1(如果不是1就代表有其他因子)
public boolean isUgly(int n) {
if(n<=0) return false;
int[] factors = {
2,3,5};
for(int factor:factors)
{
while(n%factor == 0)
n /= factor;
}
return n==1;
}
时间复杂度取决于整除的次数,所以至少是O(logn),空间复杂度O(1)
3.lc7 整数反转
描述:
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)
示例:
输入:x = 123 输出:321
输入:x = -123 输出:-321
Solution:
关键就在于不能用long!(不允许存储 64 位整数),因为你反转之后可能会溢出,所以一定是要在反转之前就判断它是否会溢出!
采取的方法是
public int reverse(int x) {
int result = 0;
while(x!=0)
{
if (result < Integer.MIN_VALUE / 10 || result > Integer.MAX_VALUE / 10)
return 0;
int tmp = x%10;
result = result*10 +tmp;
x = x/10;
}
return result;
}
4.lc2562 找出数组的串联值
lc2563 链接——lc332场周赛
示例:
输入:nums = [7,52,2,4]
输出:596
解释:74+522=596
Solution:
在这里插入代码片
5.lc415 字符串相加
描述:
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回(不能转化为整数)
示例:
输入:num1 = “11”, num2 = “123” 输出:“134”
Solution:
模拟进位即可,将两个字符串末尾对齐,记录进位和余数
public String addStrings(String num1, String num2) {
int i = num1.length()-1 ,j= num2.length()-1;
StringBuilder res = new StringBuilder();
int carry=0;
while(i>=0 ||j>=0)
{
int a =i>=0? num1.charAt(i)-'0':0;
int b =j>=0? num2.charAt(j)-'0':0;
int tmp = a+b+carry;
carry = tmp/10;
res.append(tmp%10);
i--;
j--;
}
if(carry==1) res.append(1);
return res.reverse().toString();
与这题类似的还有 lc67二进制求和 https://leetcode.cn/problems/add-binary/,也是一样的思想,相当于本题是十进制,lc67是二进制。