[Leetcode] 248. Strobogrammatic Number III

本文介绍了一种使用穷举加过滤的方法解决旋转数问题的技术。通过StrobogrammaticNumberII问题的延伸,文章详细阐述了如何生成指定范围内的旋转数解集,并提供了具体的Java实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

刚看这一题的时候觉得是要返回number,以为是有什么取巧的方式,思前想后发现取巧的方式太复杂,看了一下别人的答案,结果发现还是要用穷举加过滤。也就是说大家的解基本都是能够得到全部解集而不仅仅是一个数字作为答案的。只能说我想多了。

既然是穷举加过滤,那么方法其实不是很复杂,是Strobogrammatic Number II的一种延伸。
在Strobogrammatic Number II里面,我们可以得到某个长度的解集。而这一题,我们就可以利用这个解。得到不同长度的解集,然后在low这个长度上和high这个长度上进行字符串比较从而过滤掉范围外的答案。
举个例子,50 到 10000, 那么我们就有了四个长度: 2, 3, 4, 5

我们通过Strobogrammatic Number II 的方式进行求解集,然后再长度2和5的时候分别与low或者high进行字符串比较即可。
 

    public int strobogrammaticInRange(String low, String high) {
        if (low.length() > high.length() || (low.length() == high.length() && low.compareTo(high) > 0)) return 0;
        Map<Character, Character> diffMap = new HashMap<>();
        diffMap.put('6', '9');
        diffMap.put('9', '6');
        diffMap.put('0', '0');
        diffMap.put('1', '1');
        diffMap.put('8', '8');
        int result = 0;
        for (int i = 0; i <= high.length() - low.length(); i++) {
            result += countStrobo(low, high, 0, new char[low.length() + i], diffMap);
        }
        
        return result;
    }
    
    public int countStrobo(String low, String high, int curPos, char[] cache, Map<Character, Character> diffMap) {
        int result = 0;
        for (Map.Entry<Character, Character> entry : diffMap.entrySet()) {
            int reverse = cache.length - curPos - 1;
            char ch = entry.getKey();
            char reversed = entry.getValue();
            if (reverse == curPos && (ch == '6' || ch == '9')) continue;
            cache[curPos] = ch;
            cache[reverse] = reversed;
            if (reverse - curPos > 1) {
                if (curPos == 0 && ch == '0') continue;
                result += countStrobo(low, high, curPos + 1, cache, diffMap);
            } else {
                if (curPos == 0 && ch == '0' && reverse != curPos) continue;
                String candi = new String(cache);
                boolean pass = true;
                if (cache.length == low.length()) {
                    pass &= candi.compareTo(low) >= 0;
                }

                if (pass && cache.length == high.length()) {
                    pass &= candi.compareTo(high) <= 0;
                }
                        
                result += pass ? 1 : 0;
            }
        }
        
        return result;
    }

 

事实上我们可以通过再加一点代码进行截肢操作,这样还可以省一半的时间,但有没有必要就见仁见智了。毕竟代码已经不短了

    public int strobogrammaticInRange(String low, String high) {
        if (low.length() > high.length() || (low.length() == high.length() && low.compareTo(high) > 0)) return 0;
        Map<Character, Character> diffMap = new HashMap<>();
        diffMap.put('6', '9');
        diffMap.put('9', '6');
        diffMap.put('0', '0');
        diffMap.put('1', '1');
        diffMap.put('8', '8');
        int result = 0;
        for (int i = 0; i <= high.length() - low.length(); i++) {
            result += countStrobo(low, high, 0, new char[low.length() + i], diffMap, true, true);
        }
        
        return result;
    }
    
    public int countStrobo(String low, String high, int curPos, char[] cache, Map<Character, Character> diffMap, boolean lowEqual, boolean highEqual) {
        int result = 0;
        int reverse = cache.length - curPos - 1;
        Character lowCh = curPos < low.length() ? low.charAt(curPos) : null;
        Character highCh = high.charAt(curPos);
        for (Map.Entry<Character, Character> entry : diffMap.entrySet()) {
            char ch = entry.getKey();
            char reversed = entry.getValue();
            if (reverse == curPos && (ch == '6' || ch == '9')) continue;
            cache[curPos] = ch;
            cache[reverse] = reversed;
            if (reverse - curPos > 1) {
                if (curPos == 0 && ch == '0') continue;
                if (lowEqual && lowCh != null) {
                    if (cache.length == low.length()) {
                        if (lowCh > ch) continue;
                    }
                }
                
                if (highEqual) {
                    if (cache.length == high.length()) {
                        if (highCh < ch) continue;
                    }
                }
                result += countStrobo(low, high, curPos + 1, cache, diffMap, lowEqual && lowCh == ch, highEqual && highCh == ch);
            } else {
                if (curPos == 0 && ch == '0' && reverse != curPos) continue;
                String candi = new String(cache);
                boolean pass = true;
                if (cache.length == low.length()) {
                    pass &= candi.compareTo(low) >= 0;
                }

                if (pass && cache.length == high.length()) {
                    pass &= candi.compareTo(high) <= 0;
                }
                        
                result += pass ? 1 : 0;
            }
        }
        
        return result;
    }


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值