剑指 Offer(第2版)面试题 17:打印从 1 到最大的 n 位数

剑指 Offer(第2版)面试题 17:打印从 1 到最大的 n 位数

  • 剑指 Offer(第2版)面试题 17:打印从 1 到最大的 n 位数
    • 解法1:字符数组
    • 解法2:全排列

剑指 Offer(第2版)面试题 17:打印从 1 到最大的 n 位数

题目描述:

输入数字n,按顺序打印出从 1 到最大的 n 位十进制数。比如:输入 3,则打印出 1,2,3 一直到最大的 3 位 999。

首先想到的是 for 循环挨个输出,但是这样的话会有 n 过大,位数过高而造成溢出的情况。

解法1:字符数组

我们使用字符串来模拟数字,这样的话不管多少位我们都可以解决:

构造字符数组:先构造一个 n 位,每一位都为 ‘0’ 的数组,每次最后一位 +1,重复这一过程到溢出为此(如 2 位,加到 100 就会溢出,因此输出 1 ~ 99)

输出:前面有 ‘0’ 的话不输出(如 “001”,应输出 “1”)

代码:

#include 
#include 
using namespace std;

void print_number(int number);
void print_arr(char *arr);
bool over(char *arr);

int main()
{
    print_number(2);

    system("pause");
    return 0;
}

void print_number(int number)
{
    char *arr = new char[number + 1];
    memset(arr, '0', number);
    arr[number] = '\0';
    while (!over(arr))
    {
        print_arr(arr);
    }
}

void print_arr(char *arr)
{ // 输出字符数组,第一个为0的话不输出
    bool start = false;
    int count = 0;
    while (!start)
    {
        if (arr[count] != '0')
            start = true;
        count++;
    }
    for (int i = count - 1; i <= strlen(arr); i++)
        cout << arr[i];
    cout << "\t";
}

bool over(char *arr)
{ // 数字加1操作
    arr[strlen(arr) - 1]++;
    int tmp = 0;
    for (int i = strlen(arr) - 1; i >= 0; i--)
    { // 进1相加
        arr[i] += tmp;
        if (arr[i] - '0' > 9)
        {
            arr[i] = '0';
            tmp = 1;
        }
        else
        {
            tmp = 0;
        }
    }
    if (arr[0] == '0' && tmp == 1)
        return true; // 判断溢出
    return false;
}

复杂度分析:

时间复杂度:O(2n-1)。

空间复杂度:O(n),用到了一个长度为 n+1 的字符数组。

解法2:全排列

同样基于字符数组,每一位的数字都是从0 ~9 之间不断变化,因此其是一个排列的问题,我们可以使用递归实现数组的排列,输出的规则同解法 1。

代码:

#include 
#include 
using namespace std;

void print_number(int number);
void print_arr(char *arr);
void permutation(char *arr, int index);

int main()
{
    print_number(2);

    system("pause");
    return 0;
}

void print_number(int number)
{
    char *arr = new char[number + 1];
    memset(arr, '0', number);
    arr[number] = '\0';
    for (int i = 0; i < 10; i++)
    {
        arr[0] = i + '0';
        permutation(arr, 0);
    }
}
void permutation(char *arr, int index)
{ // 先递归凑足n位,然后排列输出
    if (index == strlen(arr) - 1)
    {
        print_arr(arr);
        return;
    }
    for (int i = 0; i < 10; i++)
    {
        arr[index + 1] = i + '0';
        permutation(arr, index + 1);
    }
}
void print_arr(char *arr)
{ // 输出字符数组,第一个为0的话不输出
    bool start = false;
    int count = 0;
    while (!start)
    {
        if (arr[count] != '0')
            start = true;
        count++;
    }
    for (int i = count - 1; i <= strlen(arr); i++)
        cout << arr[i];
    cout << "\t";
}

复杂度分析:

时间复杂度:O(2n-1)。

空间复杂度:O(n),递归的深度为 n。

你可能感兴趣的:(剑指,Offer,C++,数据结构与算法,剑指Offer,全排列)