Java&C++题解与拓展——leetcode357.统计各位数字都不同的数字个数【么的新知识】

129 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

每日一题做题记录,参考官方和三叶的题解

题目要求

image.png

思路:排列组合

  • n=0n=0时,只有一种00,所以直接返回11
  • n=1n=1时,090∼9均符合条件,所以设初始resres1010
  • n>1n>1时,从高到低,第一位有九种选择(191∼9),第二位也是9种选择(090∼9去掉上一位数字),第三位88种选择(090∼9去掉上两位数字)……以此类推,即nn位的数符合条件的数字共有9×8×(9n+1)9\times 8\times \dots (9-n+1)个,即9×A9n19\times A_9^{n-1}个。那么只要把每种位数的结果相加即可得到答案。

Java

class Solution {
    public int countNumbersWithUniqueDigits(int n) {
        if(n == 0)
            return 1;
        int res = 10;
        int cur = 9; // 当前位可能的数字个数
        for(int i = 0; i < n - 1; i++) {
            cur *= 9 - i; //当前长度下符合条件的数字个数
            res += cur;
        }
        return res;
    }
}
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

C++

【直接cv java】

class Solution {
public:
    int countNumbersWithUniqueDigits(int n) {
        if(n == 0)
            return 1;
        int res = 10;
        int cur = 9; // 当前位可能的数字个数
        for(int i = 0; i < n - 1; i++) {
            cur *= 9 - i; //当前长度下符合条件的数字个数
            res += cur;
        }
        return res;
    }
};
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

Python【一行解决】

定义了一个可能选择的数目的数组字典,对应每一位对应的可供选择的数字个数(从choices[1]choices[1]开始分别为高到低的每一位,choices[0]choices[0]n=0n=0时的情况,用于简化代码),然后用lambda轮流去取字典里的下一位的可能数目进行计算。

choices = [1, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1]
class Solution:
    def countNumbersWithUniqueDigits(self, n: int) -> int:
        return choices[0] + sum([reduce(lambda x, y: x * y, choices[:i + 1])
            for i in range(1, n + 1)])

总结

又是考察思路逻辑的题目,理清了思路,代码实现就so easy,光速解决+1。

【线下上课第一天,刚好去找教室了】


欢迎指正与讨论!