数学的门类很多,涉及的范围很广,很多难度也超大,但是在算法中,一般只会选择各个学科的基础问题来考察,例如素数问题、幂、对数、阶乘、幂运算、初等数论、几何问题、组合数学等等。
1822. 数组元素积的符号 - 力扣(LeetCode)
已知函数 signFunc(x)
将会根据 x
的正负返回特定值:
x
是正数,返回 1
。x
是负数,返回 -1
。x
是等于 0
,返回 0
。给你一个整数数组 nums
。令 product
为数组 nums
中所有元素值的乘积。
返回 signFunc(product)
。
public int arraySign(int[] nums)
{
int count = 0; //nums 中负数的个数
for(int num : nums)
{
if(num == 0)
return 0;
else if(num < 0)
count++;
}
if(count % 2 == 1)
return -1;
else
return 1;
}
public int arraySign(int[] nums)
{
int ans = 1;
for(int num : nums)
{
if(num == 0)
return 0;
else if(num < 0)
ans = -ans; //交替
}
return ans;
}
面试题 16.05. 阶乘尾数 - 力扣(LeetCode)
设计一个算法,算出 n 阶乘有多少个尾随零。
示例 1:
输入: 3
输出: 0
解释: 3! = 6, 尾数中没有零。
示例 2:
输入: 5
输出: 1
解释: 5! = 120, 尾数中有 1 个零.
说明: 你算法的时间复杂度应为 O(log n) 。
要在末位产生0
,则必然是5×2
,因此我们需要求2 * 5
出现了几对。又因阶乘中5
出现的次数比2
少,所以将题目简化为寻找阶乘中5
的个数。
n / 5
只找到了n
中是5
倍数的所有数,例如25
,即在25!
中找到了5
个是5
的倍数的数分别为5,10,15,20,25
,要注意这之中的25
依然可以分解为5
的倍数
我们可以对n
取25的商,即n / 25
,这样就找到了包含有2个5的数(且因为是对5×5取商,没有重复计入),依此类推,可以循环对n取5, 25, 125…的商,将所有的情况都包括
n / 25 == n / 5 / 5
,因此可以对n
循环取5的商,其效果是一样的。
public int trailingZeroes(int n)
{
int count = 0;
while (n >= 5)
{
n /= 5;
count += n;
}
return count;
}
凡是涉及到输出结果为数字的问题,必须溢出问题!
7. 整数反转 - 力扣(LeetCode)
给你一个 32 位的有符号整数 x
,返回将 x
中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1]
,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
提示:
-231 <= x <= 231 - 1
public static int reverse(int x)
{
int ans = 0;
int Max = Integer.MAX_VALUE;
int Min = Integer.MIN_VALUE;
while (x != 0)
{
if(ans > Max / 10 || (ans == Max / 10 && x % 10 > Max % 10)
||
ans < Min / 10 || (ans == Min / 10 && x % 10 < Min % 10))
//负数求余结果仍是负数
return 0;
ans = 10 * ans + x % 10;
x /= 10;
}
return ans;
}
9. 回文数 - 力扣(LeetCode)
给你一个整数 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
**进阶:**你能不将整数转为字符串来解决这个问题吗?
public boolean isPalindrome(int x)
{
if(x < 0)
return false;
String s = String.format("%d", x);
char[] chars = s.toCharArray();
int left = 0;
int right = s.length() - 1;
while (left < right)
{
if(chars[left] != chars[right])
return false;
left++;
right--;
}
return true;
}
public boolean isPalindrome_2(int x)
{
//非零数末尾若是0,则反转后0在首位,不符合要求,也可直接排除
if(x < 0 || x % 10 == 0 && x != 0)
return false;
//反转
long reverse = 0; //long 类型避免反转过程中溢出
int t = x;
while (t != 0)
{
reverse = 10 * reverse + t % 10;
t /= 10;
}
return x == reverse;
}
504. 七进制数 - 力扣(LeetCode)
给定一个整数 num
,将其转化为 7 进制,并以字符串形式输出。
示例 1:
输入: num = 100
输出: "202"
示例 2:
输入: num = -7
输出: "-10"
public String convertToBase7(int num)
{
return Integer.toString(num, 7);
}
最后将余数反转过来排列
public String convertToBase7(int num)
{
StringBuilder sb = new StringBuilder();
int sign = 1;
if (num < 0)
{
sign = -1;
num = -num; //先当正数来处理
}
do
{
sb.append(num % 7);
num /= 7;
}while (num > 0);
if (sign == -1)
sb.append("-");
return sb.reverse().toString();
}
M
是32位整数,2 <= N <= 16
。
public static String convertToBaseN(int M, int N)
{
String[] F = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
StringBuilder sb = new StringBuilder();
int sign = 1;
if (M < 0)
{
sign = -1;
M = -M; //先当正数来处理
}
do
{
int mod = M % N;
//技巧一:通过数组F[]解决不同进制之间映射的问题
sb.append(F[mod]);
M /= N;
}while (M > 0);
//技巧二:最后处理正负,不要从一开始就揉在一起
if (sign == -1)
sb.append("-");
//技巧三:使用StringBuffer的reverse()方法,让原本麻烦的反转瞬间美好
return sb.reverse().toString();
}