【LeetCode - 248】中心对称数 III

1、题目描述

在这里插入图片描述

2、解题思路

  给定一个区间,比如 [50, 100]。

  先计算出下限的长度和上限的长度,分别为 2 和 3,于是分别找出长度为 2 位数的中心对称数字和长度为 3 位数的中心对称数字,接着把超出 [50, 100] 区间的数字剔除即可。

  具体算法采用递归的思路:

  1、遍历上下限的长度;

  2、对于长度为 n 的中心对称数,分别在它两侧尝试放 {‘0’, ‘0’}, {‘1’, ‘1’}, {‘8’, ‘8’}, {‘6’, ‘9’}, {‘9’, ‘6’};

  3、注意长度为 1 或者在正中间是不可以为 6 或者 9的;

  4、统计个数的时候,如果数字长度为 1,则有效;如果长度大于 1 的,则必须第一个字符不能为 ‘0’,否则就不算 n 位数字了。

3、解题代码

class Solution {
    private final char[][] mapping = {{'0', '0'}, {'1', '1'}, {'8', '8'}, {'6', '9'}, {'9', '6'}};
    public int count = 0;

    /**
     * 计算范围在 [low, high] 之间中心对称数的个数。
     *
     * @param low
     * @param high
     * @return
     */
    public int strobogrammaticInRange(String low, String high) {
        int lo = low.length();
        int hi = high.length();
        // 获取长度 [lo, hi] 区间的中心对称数
        for (int n = lo; n <= hi; n++) {
            char[] chs = new char[n];
            getStrobogrammatic(chs, 0, chs.length - 1, low, high);
        }
        return count;
    }

    /**
     * 填充可能的中心对称数到 chs
     * @param chs
     * @param lo    左指针
     * @param hi    右指针
     * @param low   下限
     * @param high  上限
     */
    public void getStrobogrammatic(char[] chs, int lo, int hi, String low, String high) {
        if (lo > hi) {  // 填充完毕,开始统计个数
            if (chs.length == 1 || chs[0] != '0') { // 如果 chs 长度为 1,则有效,否则第 0 个元素不能为 '0'
                String str = String.valueOf(chs);
                if (compare(str, low) && compare(high, str)) {
                    count++;
                }
            }
            return;
        }
        // 遍历 lo 和 hi 的可能取值
        for (char[] map : mapping) {
            if (lo == hi && map[0] != map[1]) continue; // 正中间不可以是 6 或者 9
            chs[lo] = map[0];   // 0 1 8
            chs[hi] = map[1];   // 0 1 8
            getStrobogrammatic(chs, lo + 1, hi - 1, low, high);
        }
    }

    /**
     * 判断 s1 是否大于 s2
     * @param s1
     * @param s2
     * @return
     */
    public boolean compare(String s1, String s2) {
        if (s1.length() == s2.length()) {
            if (s1.compareTo(s2) >= 0) {
                return true;
            } else {
                return false;
            }
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值