248. Strobogrammatic Number III

248. Strobogrammatic Number III


A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down).

Write a function to count the total strobogrammatic numbers that exist in the range of low <= num <= high.

Example:

Input: low = “50”, high = “100”
Output: 3
Explanation: 69, 88, and 96 are three strobogrammatic numbers.

Note:
Because the range might be a large number, the low and high numbers are represented as string.

方法1:

思路:

首先确定len = 0 和len = 1的一共4个case,然后用递归函数向两端扩展。扩展的终止条件是,current大小已经大于high了,那么一定会越界。否则我们可以定义一个comparator,以string长度排序,如果长度相等,一个字符一个字符比较。我们将符合条件的数字先计入结果,此时注意,虽然“010”这个数字可以继续向下pass扩展,但不是一个valid结果之一,所以还要再判断一次是否是current > 1 && current[0] == ‘0’, 注意当current.size() == 1的时候可以有current = 0。接下来这个current会被继续用hash表里面的数对扩展。

易错点:

  1. comparator 在定义的时候,a.size() <= b.size():这里之所以有一个等号是因为,我们希望返回闭区间,i.e. low和high本身也应该被返回true。当运行到这一句的时候我们知道ab有可能大小不等,那么直接返回size的比较值,但也有可能完全literally一样,这就是string 中的一个是high或low了,需要返回true。
  2. 不能用stoi来直接比大小,test case里会出现overflow。

Complexity

Time complexity: O(1)
Space complexity: O(len)

class Solution {
private:
    unordered_map<char, char> hash = {{'0','0'}, {'1', '1'}, {'6', '9'}, {'8', '8'}, {'9', '6'}};
    bool compare(string & a, string & b) {
        if (a.size() == b.size()) {
            for (int i = 0; i < a.size(); i++) {
                if (a[i] != b[i]) return a[i] < b[i];
            }
        }
        return a.size() <= b.size();
    }
public:
    int strobogrammaticInRange(string low, string high) {
        int res = 0;
        strobHelper(low, high, "", res);
        strobHelper(low, high, "0", res);
        strobHelper(low, high, "1", res);
        strobHelper(low, high, "8", res);
        return res;
    }
    
    void strobHelper(string low, string high, string current, int & res) {
        if (high.size() < current.size()) return;
        if (compare(low, current) && compare(current, high)) {
            if (current.size() == 1 || current.size() > 1 && current[0] != '0') res++;
        } 
        
        for (auto item: hash) {
            strobHelper(low, high, item.first + current + item.second, res);
        }
    }
};


//  错误的方法,判断何时跳过何时res++出现遗漏
class Solution1 {
private:
    unordered_map<char, char> hash = {{'0','0'}, {'1', '1'}, {'6', '9'}, {'8', '8'}, {'9', '6'}};
public:
    int strobogrammaticInRange(string low, string high) {
        int res = 0;
        strobHelper(low, high, "", res);
        strobHelper(low, high, "0", res);
        strobHelper(low, high, "1", res);
        strobHelper(low, high, "8", res);
        return res;
    }
    
    void strobHelper(string low, string high, string current, int & res) {
        if(current.size() >= low.size() && current.size() <= high.size()) {
            // 注意这里的写法不对,不能在扩展中途直接消掉"010",因为还可能继续发展成“80108”
            if (current.compare(low) < 0 || current.size() > 1 && current[0] == '0' || current.size() == high.size() && current.compare(high) > 0) return;
            res++;
            // cout << current << endl;
        }
        
        if (current.size() + 2 > high.size()) return;
        for (auto item: hash) {
            strobHelper(low, high, item.first + current + item.second, res);
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值