Leetcode 902.最大为N的数字组合【深度优先搜索】

问题描述

我们有一组排序的数字 D,它是 {‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’} 的非空子集。(请注意,‘0’ 不包括在内。)

现在,我们用这些数字进行组合写数字,想用多少次就用多少次。例如 D = {‘1’,‘3’,‘5’},我们可以写出像 ‘13’, ‘551’, ‘1351315’ 这样的数字。

返回可以用 D 中的数字写出的小于或等于 N 的正整数的数目。

示例 1:

输入:D = [“1”,“3”,“5”,“7”], N = 100
输出:20
解释:
可写出的 20 个数字是:
1, 3, 5, 7, 11, 13, 15, 17, 31, 33, 35, 37, 51, 53, 55, 57, 71, 73, 75, 77.

解题报告

待完善

实现代码

  • 我的代码,浅度剪枝【TLE】
深度有限搜索【TLE】
class Solution {
public:
    int atMostNGivenDigitSet(vector<string>& D, int N) {
        int ans=0,tmpN=N,nbit=0;
        while(tmpN){
            tmpN/=10;
            nbit++;
            ans+=pow(D.size(), nbit);
        }
        ans-=pow(D.size(),nbit);
        DFS(ans, D, N, 0, 0, nbit);
        return ans;
    }
    void DFS(int &ans, vector<string>& D, int N, int index, long sum, int nbit){
        if(index==nbit)ans++;
        else{
            for(int i=0;i<D.size();i++){
                if(sum*10+atoi(D[i].c_str())<=N)
                    DFS(ans, D, N, index+1, sum*10+atoi(D[i].c_str()), nbit);
                else
                    return ;
            }
        }
    }
};
  • 别人的代码,深度剪枝
class Solution {
public:
    int res=0,f=0;
    int jisuan(int m,int n){
        if(m==0) return 0;
        int sum=0,x=1;
        while(m){
            x=x*n;
           sum+=x;
           m--; 
        }
        return sum;
    }
    int dfs(vector<string>& D,string s,int pos){
        if(pos==s.size()) return 1;//递归到了最后,表示每一位都是确定的,这也是一个答案,和N相等,所以返回1
        int i;
        for(i=D.size()-1;i>=0;i--){
            if(s[pos]>=D[i][0]){
                break;//找到D中大于等于当前位的
            }
        }
        if(i>=0){
            if(s[pos]>D[i][0]) return (i+1)*pow(D.size(),s.size()-pos-1);//不存在和当前位相等的,则不需要继续往下,后面的位取D中所有的数
            else if(s[pos]==D[i][0]) return i*pow(D.size(),s.size()-pos-1)+dfs(D,s,pos+1);//存在和当前位相等的,先计算D中有几个比当前位小的,计算出符合条件的数,再需要继续往下
        }
        return 0;//D中的数都比当前位大,则不需要再往下
    }
    int atMostNGivenDigitSet(vector<string>& D, int N) {
        string s=to_string(N);
        res+=jisuan(s.size()-1,D.size());
        // cout<<res<<endl;
        res+=dfs(D,s,0);        
        return res;
    }
};

参考资料

[1] Leetcode 902.最大为N的数字组合
[2] 世界哪有真情

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值