算法通关村—数学统计问题处理模板

1. 数字统计专题

1.1 数组元素积的符号

数组元素积的符号
已知函数 signFunc(x) 将会根据 x 的正负返回特定值:

如果 x 是正数,返回 1 。
如果 x 是负数,返回 -1 。
如果 x 是等于 0 ,返回 0 。
给你一个整数数组 nums 。令 product 为数组 nums 中所有元素值的乘积。
返回 signFunc(product) 。

1.1.1 遍历

思路很简单,先设置一个计数1,遍历数组,如果元素等于0,那么就直接返回0,如果元素小于0,那么计数就是负的,正数就不需要考虑了。

    public int arraySign(int[] nums) {
        int res = 1;
        for(int i=0;i<nums.length;i++){
            if(nums[i] == 0){
               return 0;
            }else if(nums[i] < 0){
                res*=-1;
            }
        }
        return res;
    }

1.2 阶乘尾数

阶乘尾数
设计一个算法,算出 n 阶乘有多少个尾随零。

示例 1:

输入: 3
输出: 0
解释: 3! = 6, 尾数中没有零。
示例 2:

输入: 5
输出: 1
解释: 5! = 120, 尾数中有 1 个零.
说明: 你算法的时间复杂度应为 O(log n) 。

1.2.1 5的倍数

由于题目限制,所以肯定不能算出阶乘的值然后统计0的个数,通过不了。要产生0的条件就是2和5出现的对数,不过因为2的出现次数肯定大于5的次数,所以可以只考虑5出现的个数,5出现一次,就是一个0。

   public int trailingZeroes(int n) {
        int count =0;
        for(long num =5;n/num>0;num*=5){
            count+=n/num;
        }
        return count;
    }

2. 整数溢出

2.1 整数反转

整数反转
给你一个 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

2.1.1 反转

如果不考虑溢出的情况就是普通的反转,先找出x%10的余数temp,这个就是新的首位,然后x就是变成x/10,取得剩下来的数,但是有了溢出,就需要判断每次的结果是不是再Integer的范围内,基本判断方式就是(res > Integer.MAX_VALUE || (res == Integer.MIN_VALUE && temp >7)), 这样写主要是Integer的最大值的末尾是7,很显然不可能比7大,Integer的最小值也是一样,不过就是temp<-8

 public int reverse(int x) {
        int rev = 0;
        while(x!=0){
            int temp  = x%10;
            if(rev>Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE/10 && temp>7)){
                return 0;
            }
            if(rev<Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE/10 && temp<-8)){
                return 0;
            }
            rev = rev*10+temp;
            x=x/10;
        }
    return rev;
    }

2. 2 字符串转换整数 (atoi)

字符串转换为整数
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,“123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
注意:

本题中的空白字符只包括空格字符 ’ ’ 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

2.2.2 字符串转整数

根据题目,步骤基本就是判断的是否为空格,判断是否为正负,判断是否位数字,中间还要判断是否为Integer的最大最小值

 public int myAtoi(String s) {
        int length = s.length();
        char [] chars = s.toCharArray();
        int index =0;
        // 排除无用空格
        while(index <length  && chars[index] == ' '){
            index++;
        }
        // 排除特殊情况,"    "
        if(length ==index){
            return 0;
        }

        // 正负数判断
        int sign = 1;
        char fistChar = chars[index];
        if(fistChar == '+'){
            index++;
        }else if(fistChar == '-'){
            index++;
            sign = -1;
        }

        // 判断数字
        int res = 0;
        while(index <length){
            char currentChar = chars[index];
            if(currentChar >= '0' && currentChar<='9'){
                if(res>Integer.MAX_VALUE/10 || (res == Integer.MAX_VALUE/10 && (currentChar-'0') >Integer.MAX_VALUE%10)){
                    return Integer.MAX_VALUE;
                }
                if(res<Integer.MIN_VALUE/10 || (res == Integer.MIN_VALUE/10 && (currentChar-'0') >-(Integer.MIN_VALUE%10))){
                    return Integer.MIN_VALUE;
                }

             res = res*10+(currentChar-'0')*sign;   
             index++;
            }else{
                break;
            }
        }
        return res;
    }

2.3 回文数

回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

例如,121 是回文,而 123 不是。

2.3.1 简单方法

首先可以先排除负数,负数时肯定不满足回文数的,然后就是普通的回文数方法,不过需要先记录好原来的x值,因为经过变化后x不是原来的值了。

    public boolean isPalindrome(int x) {
        int num = x;
        if(x <0) return false;
        int res = 0;
        while(x!=0){
            int temp = x%10;
            res = res*10+temp;
            x= x/10;
        }
        return num == res;
    }

3. 进制专题

3.1 七进制数

七进制数
给定一个整数 num,将其转化为 7 进制,并以字符串形式输出。

示例 1:

输入: num = 100
输出: “202”
示例 2:

输入: num = -7
输出: “-10”

3.1.1

题目需要返回string类型的字符串,转换为7进制就是将相应的数取余数,num%7就可以了,不过需要使用标志位记住当前符号,将这个数转换为正数计算,然后再进行字符串拼接,逆序就是最终的结果。

public String convertToBase7(int num) {
        StringBuilder sb = new StringBuilder();
        // 记住正负
        boolean flag = num>=0;
        if(!flag){
            num*=-1;
        }
		// 循环拼接余数
        do{
            sb.append(num%7+"");
            num/=7;
        }while(num>0);

        if(!flag){
            sb.append("-");
        }
		// 字符串逆序
        return sb.reverse().toString();
    }

3.2 任意进制转换

采用数组保存2-16各个进制值得对应标记,进行赋值得时候,只会计算下标。
使用flag标志正负
StringBuilder完成字符串逆转

    public static final String[] F = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};

    public static String convert(int M, int N) {
        boolean flag = true;
        if (M < 0) {
            flag = false;
            M *= -1;
        }
        StringBuilder sb = new StringBuilder();
        int temp;
        while (M != 0) {
            temp = M % N;
            sb.append(F[temp]);
            M = M / N;
        }
        if (!flag) {
            sb.append("-");
        }
        return sb.reverse().toString();
    }

你可能感兴趣的:(算法)