[LeetCode] Strobogrammatic Number II 对称数之二

简介:

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

Find all strobogrammatic numbers that are of length = n.

For example,
Given n = 2, return ["11","69","88","96"].

Hint:

  1. Try to use recursion and notice that it should recurse with n - 2 instead of n - 1.

这道题是之前那道Strobogrammatic Number的拓展,那道题让我们判断一个数是否是对称数,而这道题让我们找出长度为n的所有的对称数,我们肯定不能一个数一个数的来判断,那样太不高效了,而且OJ肯定也不会答应。题目中给了提示说可以用递归来做,而且提示了递归调用n-2,而不是n-1。我们先来列举一下n为0,1,2,3,4的情况:

n = 0:   none

n = 1:   0, 1, 8

n = 2:   11, 69, 88, 96

n = 3:   101, 609, 808, 906, 111, 619, 818, 916, 181, 689, 888, 986

n = 4:   1001, 6009, 8008, 9006, 1111, 6119, 8118, 9116, 1691, 6699, 8698, 9696, 1881, 6889, 8888, 9886, 1961, 6969, 8968, 9966

我们注意观察n=0和n=2,可以发现后者是在前者的基础上,每个数字的左右增加了[1 1], [6 9], [8 8], [9 6],看n=1和n=3更加明显,在0的左右增加[1 1],变成了101, 在0的左右增加[6 9],变成了609, 在0的左右增加[8 8],变成了808, 在0的左右增加[9 6],变成了906, 然后在分别在1和8的左右两边加那四组数,我们实际上是从m=0层开始,一层一层往上加的,需要注意的是当加到了n层的时候,左右两边不能加[0 0],因为0不能出现在两位数及多位数的开头,在中间递归的过程中,需要有在数字左右两边各加上0的那种情况,参见代码如下:  

解法一:

class Solution {
public:
    vector<string> findStrobogrammatic(int n) {
        return find(n, n);
    }
    vector<string> find(int m, int n) {
        if (m == 0) return {""};
        if (m == 1) return {"0", "1", "8"};
        vector<string> t = find(m - 2, n), res;
        for (auto a : t) {
            if (m != n) res.push_back("0" + a + "0");
            res.push_back("1" + a + "1");
            res.push_back("6" + a + "9");
            res.push_back("8" + a + "8");
            res.push_back("9" + a + "6");
        }
        return res;
    }
};

这道题还有迭代的解法,感觉也相当的巧妙,需要从奇偶来考虑,奇数赋为0,1,8,偶数赋为空,如果是奇数,就从i=3开始搭建,因为计算i=3需要i=1,而我们已经初始化了i=1的情况,如果是偶数,我们从i=2开始搭建,我们也已经初始化了i=0的情况,所以我们可以用for循环来搭建到i=n的情况,思路和递归一样,写法不同而已,参见代码如下:

解法二:

class Solution {
public:
    vector<string> findStrobogrammatic(int n) {
        vector<string> one{"0", "1", "8"}, two{""}, res = two;
        if (n % 2 == 1) res = one;
        for (int i = (n % 2) + 2; i <= n; ++i) {
            vector<string> t;
            for (auto a : res) {
                if (i != n) t.push_back("0" + a + "0");
                t.push_back("1" + a + "1");
                t.push_back("6" + a + "9");
                t.push_back("8" + a + "8");
                t.push_back("9" + a + "6");
            }
            res = t;
        }
        return res;
    }
};

本文转自博客园Grandyang的博客,原文链接:对称数之二[LeetCode] Strobogrammatic Number II ,如需转载请自行联系原博主。

相关文章
|
7月前
|
算法
Leetcode 313. Super Ugly Number
题目翻译成中文是『超级丑数』,啥叫丑数?丑数就是素因子只有2,3,5的数,7 14 21不是丑数,因为他们都有7这个素数。 这里的超级丑数只是对丑数的一个扩展,超级丑数的素因子不再仅限于2 3 5,而是由题目给定一个素数数组。与朴素丑数算法相比,只是将素因子变了而已,解法还是和朴素丑数一致的。
68 1
|
5天前
|
存储 SQL 算法
LeetCode 题目 65:有效数字(Valid Number)【python】
LeetCode 题目 65:有效数字(Valid Number)【python】
|
30天前
|
存储 算法
【LeetCode力扣】单调栈解决Next Greater Number(下一个更大值)问题
【LeetCode力扣】单调栈解决Next Greater Number(下一个更大值)问题
13 0
|
7月前
|
存储
Leetcode Single Number II (面试题推荐)
给你一个整数数组,每个元素出现了三次,但只有一个元素出现了一次,让你找出这个数,要求线性的时间复杂度,不使用额外空间。
23 0
LeetCode contest 190 5417. 定长子串中元音的最大数目 Maximum Number of Vowels in a Substring of Given Length
LeetCode contest 190 5417. 定长子串中元音的最大数目 Maximum Number of Vowels in a Substring of Given Length
LeetCode Contest 178-1365. 有多少小于当前数字的数字 How Many Numbers Are Smaller Than the Current Number
LeetCode Contest 178-1365. 有多少小于当前数字的数字 How Many Numbers Are Smaller Than the Current Number
LeetCode 136. 只出现一次的数字 Single Number
LeetCode 136. 只出现一次的数字 Single Number
LeetCode contest 177 5169. 日期之间隔几天 Number of Days Between Two Dates
LeetCode contest 177 5169. 日期之间隔几天 Number of Days Between Two Dates
|
人工智能 算法
LeetCode 1347. 制造字母异位词的最小步骤数 Minimum Number of Steps to Make Two Strings Anagram
LeetCode 1347. 制造字母异位词的最小步骤数 Minimum Number of Steps to Make Two Strings Anagram
LeetCode 1342. 将数字变成 0 的操作次数 Number of Steps to Reduce a Number to Zero
LeetCode 1342. 将数字变成 0 的操作次数 Number of Steps to Reduce a Number to Zero