【剑指offer17】打印从1到最大的n位数

被力扣简化的原版:剑指offer面试题17:打印从1到最大的n位数

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

分析思路

需要解决的问题:

  • 考虑大数问题:
    题目没有要求n的取值范围,所以会有int或者long型都溢出的可能。要求我们要用字符串来表示数字。
  • 打印问题:
    需要考虑如何打印出字符串表示的数。由于类似"00123"前导0的存在,我们要打印出符合我们阅读习惯的数字123,而不是00123,需要额外定义一个打印方法,这个PrintNumber函数从首个非0字符才开始打印。
  • 如何得到从1到最大n位数
    如果在数字前补0,那么n位所有十进制的数字其实就是n个从0到9的全排列,利用递归我们可以轻松实现。

代码实现

首先是对全排列的实现:

void Print1ToMaxOfDigits(int n) {
    //对n取值范围的维护
    if (n <= 0) {
      return;
    }
    char[] number = new char[n];
    for (int i = 0; i < 10; i++) {
      number[0] = (char) (i + '0');
      Print1ToMaxOfDigitsOrderly(number, n, 0);
    }
  }
	//@param
	//length:共n位数;
	//index:记录已经填充好的位数;
  void Print1ToMaxOfDigitsOrderly(char[] number, int length, int index) {
    //当前n位数是否排列好
    if (length - 1 == index) {
      PrintNumber(number);
      return;
    }
    //因为index位已经排列好,所以当前次递归排列的是index+1位
    for (int i = 0; i < 10; i++) {
      number[index + 1] = (char) (i + '0');
      Print1ToMaxOfDigitsOrderly(number, length, index + 1);
    }
  }

接下来实现PrintNumber函数:

void PrintNumber(char[] number) {
    boolean isBegin0 = true;//判断当前0是否为前导0
    int len = number.length;
    for (int i = 0; i < len; i++) {
    	//首个非0字符,此后的0都是有效数位
      if (number[i] != '0' && isBegin0) {
        isBegin0 = false;
      }
      //只打印有效数位
      if (!isBegin0) {
        System.out.print(number[i]);
      }
    }
    System.out.println();
  }

反思

书中提出一个char字符表示0~9的一个数字,浪费了8bit的char型字符能表达的256个字符的内存,能否提出更高效的方法实现?
请等待后续更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值