[Java] dfs+memo+bit
\nclass Solution {\n    int dp[][][];\n    public int numDupDigitsAtMostN(int N) {\n        //at least 1 repeat digit\n        if(N<=10)return 0;\n        Strin
```\nclass Solution {\n    int dp[][][];\n    public int numDupDigitsAtMostN(int N) {\n        //at least 1 repeat digit\n        if(N<=10)return 0;\n        String s=N+"";\n        int cnt=0;\n        int first=s.charAt(0)-\'0\';\n        dp=new int[s.length()][1<<10][2];\n        \n        for(int i=0;i<dp.length;i++){\n            for(int j=0;j<dp[0].length;j++){\n                Arrays.fill(dp[i][j],-1);\n            }\n        }\n        \n        for(int i=1;i<=first;i++){\n            if(i==first){\n                cnt+=dfs(s,1,1<<i,1);\n            }else{\n                cnt+=dfs(s,1,1<<i,0);\n            }\n        }\n        cnt+=dfs(s,1,0,0);//0 \n        return N-cnt;\n    }\n    \n    public int dfs(String s,int index,int bit,int state){\n        if(index>=s.length())return 1;\n        if(dp[index][bit][state]!=-1)return dp[index][bit][state];\n        int digit=s.charAt(index)-\'0\';\n        int res=0;\n        if(state==1){//smae prefix\n            for(int i=0;i<=digit;i++){\n                if((bit&(1<<i))!=0)continue;\n                if(i==digit){\n                    res+=dfs(s,index+1,(bit|(1<<i)),1);\n                }else{\n                    res+=dfs(s,index+1,(bit|(1<<i)),0);\n                }\n            }\n            \n        }else{\n            for(int i=0;i<10;i++){\n                if((bit&(1<<i))!=0)continue;\n                if(i==0&&bit==0&&index==s.length()-1)continue;\n                if(i==0&&bit==0)res+=dfs(s,index+1,0,0);\n                else res+=dfs(s,index+1,(bit|(1<<i)),0);\n            }\n            \n        }\n        dp[index][bit][state]=res;\n        return res;\n    }\n\n}\n\n```
[]