至少有 1 位重复的数字
难度:
标签:
题目描述
代码结果
运行时间: 32 ms, 内存: 0.0 MB
/*
* 题目思路:
* 使用 Java Stream 遍历每个数字,转换为字符串后检查是否有重复字符。
*/
import java.util.stream.IntStream;
import java.util.Set;
import java.util.HashSet;
public class Solution {
public int numDupDigitsAtMostN(int n) {
return (int) IntStream.rangeClosed(1, n)
.filter(this::hasRepeatedDigits)
.count();
}
private boolean hasRepeatedDigits(int num) {
String numStr = Integer.toString(num);
Set<Character> digits = new HashSet<>();
for (char ch : numStr.toCharArray()) {
if (digits.contains(ch)) {
return true;
}
digits.add(ch);
}
return false;
}
}
解释
方法:
这个解法使用的是组合数学中的排列组合原理来解决问题。首先,算法试图计算从1到N所有不包含重复数字的数的数量,然后从总数N中减去这个值来得到至少包含一个重复数字的数的数量。算法首先计算较短的长度(如1位数,2位数等)的所有可能的不重复数字的组合。对于每一个长度,我们首先选择第一位数字(不能为0除了长度为1的情况),然后选择剩余位置的数字(可以从剩余的9个数字中选择)。然后,算法检查N自身的每一位,确保之前的数字没有重复,并计算剩余位的可能性。如果在任何点发现重复,循环将停止。
时间复杂度:
O(L^2) 其中 L 是 N 的位数长度,这可以近似为 O((log N)^2)
空间复杂度:
O(L) 其中 L 是 N 的位数长度
代码细节讲解
🦆
在算法中,你是如何确定所有小于N的位数来计算不包含重复数字的数字数量?
▷🦆
为什么在计算不重复数字的数量时,第一位数字不能为0,除了长度为1的情况外?
▷🦆
在fac函数中,为什么选择使用循环而不是直接使用递归或内置函数来计算阶乘?
▷🦆
在检查N自身的每一位数字时,如何确保算法的效率以及处理大数字时的性能?
▷