LeetCode 172. 阶乘后的零 / 682. 棒球比赛 / 2028. 找出缺失的观测数据

172. 阶乘后的零

2022.3.25 每日一题

题目描述

给定一个整数 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 <= 10^4

进阶:你可以设计并实现对数时间复杂度的算法来解决此问题吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/factorial-trailing-zeroes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

找到规律,写出On的复杂度是不难的

class Solution {
    public int trailingZeroes(int n) {
        // 1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600 6227020800 87178291200 1307674368000
        //首先可以看到第一点,偶数乘以奇数,结果是偶数,所有的数都是偶数
        //然后第二点,怎么才能出现0呢,首先碰到10,20,30...这种,肯定会多一个0
        //然后就是说碰到5,5,15,25这种,如果尾数数偶数的话,就会多一个0
        //那所有数的尾数是不是都是偶数呢,应该是肯定的
        //所以就得到了规律,碰到5的倍数,就会多一个0,如果遇到的是25 50这种,因为是5 * 5, 5 * 2 * 5
        //所以都会多两个0
        //所以呢,就是记录有多少个5,那么遍历5的所有倍数,然后统计有多少个5,就有多少个0
        //这个复杂度是On
        int count = 0;
        int num = 5;
        while(num <= n){
            int temp = 0;
            int t = num;
            while(num % 5 ==0){
                num = num / 5;
                temp++;
            }
            count += temp;
            num = t + 5;
        }
        return count;
    }
}

官方给的这个解释更加科学,因为10=2 * 5,找0就相当于在找质因子2 和质因子5的个数的最小值
而质因子5的个数明显要小于等于2的个数,所以统计5的个数
而上面我们也可以发现,无非是在统计5的倍数,5*5的倍数,5 * 5 * 5的倍数…
那么就有了下面这个表达式
在这里插入图片描述

根据这个表达式,就可以写出logn的代码,只需要一直除5,然后将商加起来就行了

class Solution {
    public int trailingZeroes(int n) {
        int count = 0;
        while(n != 0){
            n /= 5;
            count += n;
        }
        return count;
    }
}

682. 棒球比赛

2022.3.26 每日一题

题目描述

你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。

比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:

  1. 整数 x - 表示本回合新获得分数 x
  2. “+” - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。
  3. “D” - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。
  4. “C” - 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。

请你返回记录中所有得分的总和。

示例 1:

输入:ops = [“5”,“2”,“C”,“D”,"+"]
输出:30
解释:
“5” - 记录加 5 ,记录现在是 [5]
“2” - 记录加 2 ,记录现在是 [5, 2]
“C” - 使前一次得分的记录无效并将其移除,记录现在是 [5].
“D” - 记录加 2 * 5 = 10 ,记录现在是 [5, 10].
“+” - 记录加 5 + 10 = 15 ,记录现在是 [5, 10, 15].
所有得分的总和 5 + 10 + 15 = 30

示例 2:

输入:ops = [“5”,"-2",“4”,“C”,“D”,“9”,"+","+"]
输出:27
解释:
“5” - 记录加 5 ,记录现在是 [5]
“-2” - 记录加 -2 ,记录现在是 [5, -2]
“4” - 记录加 4 ,记录现在是 [5, -2, 4]
“C” - 使前一次得分的记录无效并将其移除,记录现在是 [5, -2]
“D” - 记录加 2 * -2 = -4 ,记录现在是 [5, -2, -4]
“9” - 记录加 9 ,记录现在是 [5, -2, -4, 9]
“+” - 记录加 -4 + 9 = 5 ,记录现在是 [5, -2, -4, 9, 5]
“+” - 记录加 9 + 5 = 14 ,记录现在是 [5, -2, -4, 9, 5, 14]
所有得分的总和 5 + -2 + -4 + 9 + 5 + 14 = 27

示例 3:

输入:ops = [“1”]
输出:1

提示:

1 <= ops.length <= 1000
ops[i] 为 “C”、“D”、"+",或者一个表示整数的字符串。整数范围是 [-3 * 10^4, 3 * 10^4]
对于 “+” 操作,题目数据保证记录此操作时前面总是存在两个有效的分数
对于 “C” 和 “D” 操作,题目数据保证记录此操作时前面总是存在一个有效的分数

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/baseball-game
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

class Solution {
    public int calPoints(String[] ops) {
        //直接模拟
        List<Integer> list = new ArrayList<>();
        int n = ops.length;
        for(int i = 0; i < n; i++){
            String s = ops[i];
            int last = list.isEmpty() ? 0 : list.get(list.size() - 1);
            if(s.equals("C")){
                list.remove(list.size() - 1);
            }else if(s.equals("D")){
                list.add(2 * last);
            }else if(s.equals("+")){
                list.add(last + list.get(list.size() - 2));
            }else{
                int t = Integer.parseInt(s);
                list.add(t);
            }
        }
        int sum = 0;
        for(int t : list){
            sum += t;
        }
        return sum;
    }
}

2028. 找出缺失的观测数据

2022.3.27 每日一题

题目描述

现有一份 n + m 次投掷单个 六面 骰子的观测数据,骰子的每个面从 1 到 6 编号。观测数据中缺失了 n 份,你手上只拿到剩余 m 次投掷的数据。幸好你有之前计算过的这 n + m 次投掷数据的 平均值 。

给你一个长度为 m 的整数数组 rolls ,其中 rolls[i] 是第 i 次观测的值。同时给你两个整数 mean 和 n 。

返回一个长度为 n 的数组,包含所有缺失的观测数据,且满足这 n + m 次投掷的 平均值 是 mean 。如果存在多组符合要求的答案,只需要返回其中任意一组即可。如果不存在答案,返回一个空数组。

k 个数字的 平均值 为这些数字求和后再除以 k 。

注意 mean 是一个整数,所以 n + m 次投掷的总和需要被 n + m 整除。

示例 1:

输入:rolls = [3,2,4,3], mean = 4, n = 2
输出:[6,6]
解释:所有 n + m 次投掷的平均值是 (3 + 2 + 4 + 3 + 6 + 6) / 6 = 4 。

示例 2:

输入:rolls = [1,5,6], mean = 3, n = 4
输出:[2,3,2,2]
解释:所有 n + m 次投掷的平均值是 (1 + 5 + 6 + 2 + 3 + 2 + 2) / 7 = 3 。

示例 3:

输入:rolls = [1,2,3,4], mean = 6, n = 4
输出:[]
解释:无论丢失的 4 次数据是什么,平均值都不可能是 6 。

示例 4:

输入:rolls = [1], mean = 3, n = 1
输出:[5]
解释:所有 n + m 次投掷的平均值是 (1 + 5) / 2 = 3 。

提示:

m == rolls.length
1 <= n, m <= 10^5
1 <= rolls[i], mean <= 6

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-missing-observations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

简单模拟,注意骰子只能是1-6这几个数

class Solution {
    public int[] missingRolls(int[] rolls, int mean, int n) {
        int l = rolls.length;
        int len = n + l;
        int total = mean * len;
        
        int sum = 0;
        for(int t : rolls)
            sum += t;
        int need = total - sum;
        int a = need / n;
        int b = need % n;
        int[] res = new int[n];
        if((a == 6 && b != 0) || a > 6 || need < 0 || a == 0)
            return new int[]{};
        for(int i = 0; i < b; i++){
            res[i] = a + 1;
        }
        for(int i = b; i < n; i++){
            res[i] = a;
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值