问题描述:有一组排序的数字 D,它是 {‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’} 的非空子集。(请注意,‘0’ 不包括在内。)用这些数字进行组合写数字,想用多少次就用多少次。例如 D = {‘1’,‘2’,‘3’,‘5’},可以写出像 ‘22’, ‘332’, ‘13521315’ 这样的数字。返回可以用 D 中的数字写出的小于或等于 N 的正整数的数目。
例如:输入:D = [“1”,“2”,“3”], N = 1000000000
输出:29523
解释:可以写 3 个一位数字,9 个两位数字,27 个三位数字,81 个四位数字,243 个五位数字,729 个六位数字,2187 个七位数字,6561 个八位数字和 19683 个九位数字。总共,可以使用D中的数字写出 29523 个整数。
执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
内存消耗:35.8 MB, 在所有 Java 提交中击败了52.17% 的用户
实现思路:首先通过循环找出位数长度小于N的所有整数,因为可以无限次使用digits数组中的数字,所以每一位数位上的数字可能性都有digits.length个,即digits数组长度。然后就是寻找和N数位长度相同的数字的个数,我的实现思路是从高到低和从小到大递归判断,所谓从高到低就是从N的左起第一位往后依位遍历,所谓从小到大就是依次遍历digits数组中的数字(默认已按照从小到大排序完毕)。
第二步,当遍历的数组数字小于当前N的遍历位时,将结果加上后面数位的所有可能性,每一位仍是有数组长度个可能性。当遍历的数组数字等于当前N的遍历位时,则继续下一位。当N的遍历位变成最后一位时,仅需进行加一即可。
class Solution {
public int result = 0;
public String []numbers;
public int num_length;
public int atMostNGivenDigitSet(String[] digits, int n) {
String str = String.valueOf(n);
numbers = digits;
num_length = digits.length;
for(int i = 1;i < str.length();i++){
result += Math.pow(num_length,i);
}
recursion(str);
return result;
}
public void recursion(String str){
int index = str.charAt(0);
int length = str.length();
for(String temp : numbers){
if(temp.charAt(0) < index){
result += Math.max(Math.pow(num_length,length - 1),1);
continue;
}else if(temp.charAt(0) == index){
if(length != 1){
recursion(str.substring(1));
}else{
result++;
}
}
break;
}
}
}
作者:doomed-e
链接:https://leetcode-cn.com/problems/numbers-at-most-n-given-digit-set/solution/di-gui-0ms-by-doomed-e-gaj4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
改进点:all