剑指Offer面试题-17 打印从1到最大的n位数(全排列,递归)

该博客介绍了如何解决输入正整数n,从1到最大的n位数进行全排列打印的问题。由于常规方法在大数情况下存在局限,博主提出使用字符数组和递归的深度优先搜索(DFS)方法,通过限制每轮数字长度避免高位出现0,从而实现正确打印所有可能的n位数。
摘要由CSDN通过智能技术生成

题目描述

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

示例 1:
输入: n = 1
打印: 1,2,3,4,5,6,7,8,9

注意:n为正整数。每打印一个数用换行分隔。

题解

第一想法是,求出n位数的最大值,然后从1循环到那个值,并打印每个数。

public void printNumbers(int n) {
    int last = (int)Math.pow(10, n);
    int [] nums = new int[last];
    for (int i = 1 ; i < last ; i++)
    {
        System.out.println(i);
    }
}

但是,如果n到达了10,那么int类型则无法保存长达10位的数,以此类推,如果n更大,那么double类型也无法保存。

如果这题使用大数计算的话,会更加复杂。

注意到要输出1到n的所有值,那么只有用字符数组或字符串来保存这个数组,并输出。

而且这是一个全排列问题,只不过要注意一点:

  • 删除最高位之前的 0 0 0,如果使用常规全排列,当 n = 3 n = 3 n=3 时,求出的结果是 001 , 002 , 003... 001,002,003... 001002003...。很显然,我们要的结果是 1 , 2 , 3... 1,2,3... 123...

代码思路:

  • dfs函数有3个参数,now表示当前所处位数,len表示这一轮最大位数,chs为临时记录数组。dfs函数的目的是打印长度为len的所有数字,dfs(1)打印1 ~ 9,dfs(2)打印10 ~ 99,dfs(3)打印100 ~ 999。
  • 主函数中使用一个循环,从dfs(1)一直调用到dfs(n)。这样就能保证从小到大打印所有数字。
  • dfs函数内和常规全排列做法类似,只不过要注意最高位不能为0。

由于每轮dfs限制了数字的长度,那么就可以避免高位为0的情况。

public class PrintNumber
{
	public static void main(String[] args)
	{
		int n = 3;
		for (int i = 1 ; i <= n ; i++)
		{
			dfs(0, i, new char[i]);
		}
	}

	private static void dfs(int now, int len, char [] chs)
	{
		if (now >= len) {
			System.out.println(chs);
			return;
		}

		for (int i = 0 ; i < 10 ; i++)
		{
			if (now == 0 && i == 0) {
				continue;
			}
			chs[now] = (char)(i + '0');
			dfs(now + 1, len, chs);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值