面试题17-打印从1到最大的n位数

题目:

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

解题思路

综合办法是采用递归的思想。在这个题中,有面试官埋下的陷阱。我们求最大的n位数,是不是用整型(int)或者长整型(long long)都会溢出。也就是说我们需要考虑大数问题。
最常用也是最容易的方法是用字符串或者数组表达大数。在用字符串表示数字的时候,最直观的方法就是字符串里每个字符都是“0”~“9”之间的某个字符,用来表示数字中的一位。因为数字最大是n位的,因此我们需要一个长度为n+1的字符串(字符串中最后一位是结束符号“\0”)。当实际数字不够n位的时候,在字符串的前半部分补0。
如果我们在数字前面补0,就会发现n位所有十进制数其实就是n个从0到9的全排列。也就是说,我们把数字的每一位都从0到9排列一遍,就得到了所有的十进制数。只是在打印的时候,排在前面的0不打印出来罢了。
递归结束的条件是我们已经设置了数字的最后一位。

C++实现

#include<iostream>
using namespace std;

class Solution17
{
public:
	void PrintToMaxOfNDigits(int n)
	{
		if (n <= 0)
			return;
		char *number = new char[n + 1];
		number[n] = '\0';
		for (int i = 0; i < 10; i++)
		{
			number[0] = i + '0';
			PrintToMaxOfNDigitsRecursively(number, n, 0);
		}
		delete[]number;
	}
	void PrintToMaxOfNDigitsRecursively(char*number, int length, int index)
	{
		if (index == length - 1)
		{
			PrintNumber(number);
			return;
		}
		for (int i = 0; i < 10; i++)
		{
			number[index + 1] = i + '0';
			PrintToMaxOfNDigitsRecursively(number, length, index + 1);
		}
	}
	void PrintNumber(char *number)
	{
		bool isBeginning0 = true;
		int nLength = strlen(number);
		for (int i = 0; i < nLength; i++)
		{
			if (isBeginning0&&number[i] != '0')
				isBeginning0 = false;
			if (!isBeginning0)
				printf("%c", number[i]);
		}
		printf("\t");
	}
};
//测试用例
int main()
{
	Solution17 s;
	s.PrintToMaxOfNDigits(5);
	system("pause");
	return 0;
}

leetcode

class Solution:
    def printNumbers(self, n: int) -> List[int]:
        def dfs(x):
            if x==n:
                s=''.join(num[self.start:]) 
                if s!='0':res.append(int(s))
                if n-self.start==self.nine:self.start-=1
                return
            for i in range(10):
                if i==9:self.nine+=1
                num[x]=str(i)
                dfs(x+1)
            self.nine-=1
        
        num,res=['0']*n,[]
        self. nine=0
        self.start=n-1
        dfs(0)
        return res

  1. 时间复杂度 O(10^n): 递归的生成的排列的数量为 10^n。
  2. 空间复杂度 O(10^n): 结果列表 resres 的长度为 10^n - 1 ,各数字字符串的长度区间为 1,2,…,n ,因此占用 O(10^n) 大小的额外空间。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值