zoukankan      html  css  js  c++  java
  • Leetcode 1012 至少有1位重复数字

    题目描述:

      给定正整数 N,返回小于等于 N 且具有至少 1 位重复数字的正整数。

    题解:

      求至少有1位重复数字的正整数有点复杂,转换一下思路,求小于等于N没有重复数字的正整数的个数。定义一个$dp[pos][status][bound]$(dp定义解释戳这里)。这里的$status$借用了一下状压的思想,记录的是在$pos$之前0~9出现的情况。例如在$pos$之前出现了0,1,3这三个数字的时候,$status = 2^{0} + 2^{1} + 2^{3} = 9$。在设计$status$状态转移的情况的时候,要注意一下前导零的判断。$bound$的状态转移方式见代码。

    AC代码:

       

    class Solution {
    public:
        // 找出不存在重复的
        // sta 采用状压的思路 对0-9这10个数字0、1编码
        string num;
        int dp[10][1<<10][4];
        int dfs(string num,int pos,int sta,int bound)
        {
            int ans = 0;
            int l;
            if(pos >= num.size()) return 1;
            
            l = (bound & 2) ? num[pos]-'0':9;
            if(dp[pos][sta][bound] != -1) return dp[pos][sta][bound];
            for(int i=0;i<=l;i++)
            {
                if((sta>>i) & 1) continue;
                // cout << i <<endl;
                int tmp_sta = sta | (1 << i);
                int next_bound = (bound & 1? i == 0 :0) ^ (bound & 2? (i == l)<< 1 : 0);
                // 前导0的情况
                if(sta == 0 && i == 0) tmp_sta = 0;
                
                ans += dfs(num,pos+1,tmp_sta,next_bound);
            }
        
            dp[pos][sta][bound] = ans;
            return ans; 
        }
    
        int numDupDigitsAtMostN(int N) {
            num = "";
            int tmp = N;
            while(N)
            {
                num += N%10 + '0';
                N /= 10;
            }
            reverse(num.begin(),num.end());
            memset(dp,-1,sizeof(dp));
            // bound 0 1 2 3 其他 下界 上界 上下界交汇
            return tmp+1-dfs(num,0,0,3);
        }
    
    };            
  • 相关阅读:
    Hibernate--Day01
    Java语言基础之数组
    Java语言基础之方法的设计
    Jmeter-文件目录
    Jmeter-简介及安装
    测试基础-测试策略与类型
    测试基础-软件测试计划
    测试基础-软件测试流程与测试模型
    测试基础-软件测试的环境
    测试基础-软件测试目的与对象
  • 原文地址:https://www.cnblogs.com/z1141000271/p/12689547.html
Copyright © 2011-2022 走看看