数字统计专题
符号统计
问题描述
已知函数 signFunc(x) 将会根据 x 的正负返回特定值:
如果 x 是正数,返回 1 。
如果 x 是负数,返回 -1 。
如果 x 是等于 0 ,返回 0 。
给你一个整数数组 nums 。令 product 为数组 nums 中所有元素值的乘积。
返回 signFunc(product) 。
详见leetcode1822
问题分析
最直接的方式是遍历nums数组,计算各个数的乘积,判断结果的正负。这样做计算量很大,而且很可能会发生溢出问题。根据乘法同号为正,异号为负的规则,只需统计数组中负数的个数,就能判断最终结果的正负,最后,只要数组中存在一个0,则最终结果为0
代码实现
public int arraySign(int[] nums) {
int result = 1;
for(int i=0;i<nums.length;i++){
if(nums[i]==0){
return 0;
}else if(nums[i]<0){
result = -result;
}
}
return result;
}
统计阶乘尾数中的0
问题描述
设计一个算法,算出 n 阶乘有多少个尾随零。详见leetcode16.05
问题分析
直接计算阶乘结果,在统计结果中0的个数计算复杂,且可能会产生溢出问题。通过分析阶乘中的尾随0是由2(2的倍数)和5(5的倍数)运算产生的,而2(2的倍数出现的次数)总是大于5(5的倍数)出现的次数。所以,我们只需统计5(5的倍数出现的次数),就能统计阶乘结果的尾随0。
代码实现
public int trailingZeroes(int n) {
int count = 0;
while(n!=0){
n /= 5;
count += n;
}
return count;
}
溢出问题专题
整数反转
问题描述
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
问题分析
如果不考虑溢出,我们可以直接先将x对10取余,得到尾数,将x/10去掉尾数,尾数不断✖️10加上新的尾数,可以实现反转效果。代码如下
public int reverse(int x) {
int result = 0;
while(x!=0){
int temp = x%10;
result = result*10 + temp;
x = x/10;
}
return result;
}
很明显,反转后会出现数字溢出的问题。但是我们无法直接判断result>Integer.MAX_VALUE或者result<Integer.MIN_VALUE,因为此时result已经溢出了,我们可以判断result/10与最大值或者最小值除以10的关系,以最大值为例,当result/10>Integer.MAX_VALUE/10时,一定会溢出。当result/10<Integer.MAX_VALUE/10,此时下一轮不溢出,可以继续运算,当result/10==Integer.MAX_VALUE/10时,需要比较余数与Integer.MAX_VALUE%10的关系,余数>Integer.MAX_VALUE%10会溢出,否则不会溢出
代码实现
public int reverse(int x) {
int result = 0;
while(x!=0){
int temp = x%10;
if(result>Integer.MAX_VALUE/10 || (result==Integer.MAX_VALUE/10&& temp>Integer.MAX_VALUE%10)){
return 0;
}
if(result<Integer.MIN_VALUE/10 || (result==Integer.MIN_VALUE/10&&temp<Integer.MIN_VALUE%10)){
return 0;
}
result = result*10 + temp;
x = x/10;
}
return result;
}
字符串转整数
在字符串专题已经详细分析实现,详见不简单的字符串转换
回文数的判断
问题描述
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。详见leetcode9
问题分析
如果直接将整数x反转比较,运算复杂,而且可能产生溢出问题,可以反转x的一半,如果x中的个数是奇数个,最中间的一个也可以反转,判断时不算在内即可。另外特殊情况,如x是负数,x的尾数为0的情况可以单独判断。
代码实现
public boolean isPalindrome(int x) {
if(x<0){
return false;
}
if(x%10==0 && x!=0){
return false;
}
int reverse = 0;
while(x>reverse){
reverse = reverse*10 +x%10;
x = x/10;
}
return reverse==x || reverse/10==x;
}
禁止专题
七进制数
问题描述
给定一个整数 num,将其转化为 7 进制,并以字符串形式输出。
问题分析
十进制转7禁止,可以对整数num进行不断对7取余,得到的余数反转,拼接得到最终结果,题目要求最终返回的结果是字符串,那么我们可以直接用字符转拼接。
代码实现
public String convertToBase7(int num) {
if(num==0){
return "0";
}
StringBuilder sb = new StringBuilder();
boolean flag = true;
if(num<0){
flag = false;
num *= -1;
}
while(num!=0){
int temp = num%7;
sb.append(temp);
num = num/7;
}
if(!flag){
sb.append("-");
}
return sb.reverse().toString();
}
拓展:十进制转任意进制
问题描述
给定一个整数 num和一个数字n,将num转化为 n进制,并以字符串形式输出。
问题分析
思路和转换方式和上面是一样的,可自行体会代码实现
代码实现
public static String base10ToBaseN(int num, int n) {
String[] numbers = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
boolean flag = true;
StringBuilder sb = new StringBuilder();
if (num < 0) {
flag = false;
num *= -1;
}
while (num != 0) {
int temp = num % n;
sb.append(numbers[temp]);
num /= n;
}
if(!flag){
sb.append("-");
}
return sb.reverse().toString();
}
总结
数字与数学问题要灵活运用取整,取余等操作获取数字,同时要注意溢出问题。
文章来源地址https://www.toymoban.com/news/detail-702827.html
文章来源:https://www.toymoban.com/news/detail-702827.html
到了这里,关于算法通关村-----数字与数学基础问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!