LeetCode "Strobogrammatic Number III"

It can be solved based on the code from "Strobogrammatic Number II". The idea is pretty straight forward - binary search the boundaries.

class Solution 
{
    int go_cnt(int n, bool bInner)
    {
        int ret = 0;
        switch (n)
        {
        case 0:        
            ret = 1; // ""
            break;        
        case 1:
            ret = 3; //{ "0", "1", "8" };
            break;
        case 2:            
            if(bInner) ret += 1; //"00"
            ret += 4;    //{ "11", "69", "88", "96" };
            break;
        default:        
            int prev = go_cnt(n - 2, true);            
            int fac = 0;
            if(bInner) fac += 1;
            fac += 4;

            ret = fac * prev;
            break;
        }
        return ret;
    }

    vector<string> go(int n, bool bInner)
    {
        vector<string> ret;
        if (n == 0) return ret;
        if (n == 1)
        {
            ret.push_back("0");
            ret.push_back("1");
            ret.push_back("8");
        }
        else if (n == 2)
        {
            if (bInner)
            {
                ret.push_back("00");
            }
            ret.push_back("11");
            ret.push_back("69");
            ret.push_back("88");
            ret.push_back("96");
        }
        else
        {
            vector<string> prev = go(n - 2, true);
            if(bInner)
            {
                for (auto &s : prev)
                    ret.push_back('0' + s + '0');
            }
            for (auto &s : prev)
                ret.push_back("1" + s + "1");
            for (auto &s : prev)
                ret.push_back("6" + s + "9");
            for (auto &s : prev)
                ret.push_back("8" + s + "8");
            for (auto &s : prev)
                ret.push_back("9" + s + "6");
        }
        return ret;
    }
public:
    int strobogrammaticInRange(string low, string high) 
    {
        int ret = 0;
        int lenl = low.length(), lenh = high.length();
        if(lenl > lenh) return 0;

        //    complete 
        for(int j = lenl + 1; j < lenh; j ++)
            ret += go_cnt(j, false);

        int cnt0 = 0, cnt1 = 0;
        auto r0 = go(lenl, false);        
        
        auto it0 = std::lower_bound(r0.begin(), r0.end(), low);
        cnt0 = r0.end() - it0;

        if(lenh != lenl)
        {
            auto r1 = go(lenh, false);
            auto it1 = std::upper_bound(r1.begin(), r1.end(), high);
            cnt1 = it1 - r1.begin();
            
            ret += cnt0 + cnt1;
        }
        else
        {
            auto it1 = std::upper_bound(r0.begin(), r0.end(), high);
            cnt1 = it1 - r0.begin();

            ret = cnt0 + cnt1 - r0.size();
        }

        return ret;
    }
};
View Code

 Of course, we can optimize the vector generation part: we only need one part of it :)

原文地址:https://www.cnblogs.com/tonix/p/4768310.html