剑指offer(5.2)

Posted cherry-bail

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer(5.2)相关的知识,希望对你有一定的参考价值。

题目描述——给定一个数字N,打印从1到最大的N位数。

输入

每个输入文件仅包含一组测试样例。

对于每个测试案例,输入一个数字N(1<=N<=5)。 输出 对应每个测试案例,依次打印从1到最大的N位数。

样例输入

1

样例输出

1 2 3 4 5 6 7 8 9

——————————最先想到的就是,10^n 啊 ————————————

public int print(int n){

  for(int i = 1; i < 10^n; i++){

    System.out.println(i);

  }

}

但是呢,考虑一个问题。溢出

int类型是要溢出的呀,如果n太大

字符串,数组是大数的最佳存储方法

其实,从1打印到N位最大数,就是一个递归+1的过程。

用字符串模拟加法,一个字符代表一位,每个位循环输出0-9,遇10进1

想象所有数字都是N位的,1就相当于前面N-1位都为0,没有打印出来。

于是,这个递归的过程就开始清晰了

加法的过程是:1)初始化字符串为全0  2)末位加1,查看最末位是否有进位,检查溢出,如果大于等于10则产生进位,当前位减10;没有进位则结束  3)从后往前循环:往前移一位,查看是否有进位,是否溢出;遇到没有进位则结束循环。  4)打印字符串。第一个非0位之前的0全部不打印

 public void solution(int n){

  if(n < 0)  System.out.println("n cannot be negative!");

  char num[] = new char[n];

  for(int i = 0; i < num.lenght; ++i){

    num[i] = ‘0‘;

  }

  while(!increment(num)){

    Print(num);

  }

}

public boolean increment(char num){

  boolean isOverflow = false;

  int takeOver = 0;    //进位

  int sum = 0;

  for(int i = num.length-1; i >=0; i--){

    sum = num[i] - ‘0‘ + takeOver;

    if(i == num.length-1)  sum += 1;

    if(sum >= 10){

      if(i = 0){ 

        isOverflow = true;

      }else{

        sum -=10;

        overTake = 1;

        num[i] = sum + ‘0‘;

    }else{

      num[i] = sum + ‘0‘;

      break;

    }

  return isOverflow;

}

public void Print(char num){         //遇见第一个非0位才开始打印

  boolean isBeginning0 = true;          //true = 当前位字符是补充的0,无需打印

  for(int i = 0; i< num.length-1; i++){       //从字符串第一位开始打印(最高位)

    if(isBeginning && num[i] != ‘0‘){     //如果num当前位非0 或 当前位是0但不是补充的0,则接下来的所有位都可以打印,于是置isBeginning0为false

      isBeginning0 = false;

    }

    if( !isBeginning0){

      System.out.print(num[i]);

    }

  }

}

以上是关于剑指offer(5.2)的主要内容,如果未能解决你的问题,请参考以下文章

5.剑指Offer --- 优化时间和空间效率

剑指offer第二版和专项突击版有啥区别

剑指 offer 刷题记录

剑指 Offer 45. 把数组排成最小的数 剑指 Offer 61. 扑克牌中的顺子 剑指 Offer 40. 最小的k个数

剑指Offer数据结构

剑指 Offer(第 2 版)完整题解笔记 & C++代码实现(LeetCode版)