LeetCode 788. 旋转数字

788. 旋转数字

【模拟】直接验证至少包含(2,5,6,9)中的一个,可以包含(0,1,8)其他不能包含。O(nlogn)的复杂度,因为要把所有数都枚举一遍,还要枚举每个数的每一位。

class Solution {

    Set<Character> a = new HashSet(){{
        add('0');
        add('1');
        add('8');
    }};

    Set<Character> b = new HashSet(){{
        add('2');
        add('5');
        add('6');
        add('9');
    }};

    boolean count(String x) {
        int n = x.length();
        char[] s = x.toCharArray();
        int flag = 0;
        for (var i = 0; i < n; i++) {
            char c = s[i];
            if (a.contains(c)) ;
            else if (b.contains(c)) flag = 1;
            else return false;
        }
        return flag == 1;
    }

    public int rotatedDigits(int n) {

        int ans = 0;        

        for (var i = 1; i <= n; i++) {
            String str = Integer.toString(i);
            if (count(str)) ans++;
        }
        return ans;
    }
}

【数位DP】用f(pos, diff, limit)来表示第pos位,是否包含一个2,5,6,9并且不包含(3,4,7),limit表示是否受到边界限制,如果受到边界限制,那么只能填0-s[pos]范围,并且填了s[pos]后下面还是继续受限制,否则可以填0-9。

class Solution {

    // 数位dp 6:45
    // 用f(pos, diff, limit)

    int[][][] dp;
    char[] s;
    int n;
    int[] tab = new int[] {0, 0, 1, -1, -1, 1, 1, -1, 0, 1};

    public int f(int pos, int diff, boolean limit) {
        int lim = limit? 1: 0;
        if (pos == n) {
            if (diff == 0) return 0;
            return 1;
        }
        if (dp[pos][diff][lim] >= 0) {
            // System.out.println(dp[pos][diff][lim]);
            return dp[pos][diff][lim];
        }
        int up;
        if (limit) {
            up = s[pos] - '0'; 
        } else {
            up = 9;
        }
        int res = 0;
        for (var i = 0; i <= up; i++) {
            if (tab[i] != -1) {
                if (tab[i] == 1) {
                    res += f(pos + 1, 1, limit && i == up);
                    // System.out.println(ans);
                } else {
                    res += f(pos + 1, diff, limit && i == up);
                    // System.out.println(ans);
                }
            }
        }
        dp[pos][diff][lim] = res;
        return res;
    }

    public int rotatedDigits(int n) {
        s = String.valueOf(n).toCharArray();
        this.n = s.length;
        dp = new int[n + 1][2][2];
        for (var i = 0; i <= n; i++) {
            for (var j = 0; j < 2; j++) Arrays.fill(dp[i][j], -1);
        }
        return f(0, 0, true);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值