【LeetCode & 剑指offer刷题】发散思维题1:17 打印从1到最大的n位数

【LeetCode & 剑指offer刷题】发散思维题1:17 打印从1到最大的n位数

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

17 打印从1到最大的n位数

 
题目:输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999.
 
解题思路:
(1) 此题需要考虑 大数问题 ,n位数用整型(int)或者长整型(long long)容易溢出。 常用的解决办法是用字符串或者数组来表达大数
(2) 以下我们采用字符串来解决大数问题。
    可以发现n位所有十进制数其实就是n个从0到9的 全排列(不是严格意义上的全排列,返回一个数组中元素所有可能的排列形式) ,即把数字的每一位都从0到9排列一遍,就得到了所有的十进制数。只是在打印的时候, 数字排在前面的0我们不打印出来 。这种全排列采用递归的方式很容易表达。
(3) 判断输出停止条件:
    如果是最大的n位数,那么这个999.。。999再加1就会造成首位进位,也就是字符数组的第一位进位,而其他所有小于最大n位数的都不会这样,所以用这个来判断(用递归树时,无需考虑这个问题,产生10个递归分支,深度n即可)
 
#include<iostream> 
using namespace std ;  
 
void PrintMaxNDigits ( int n );  
void PrintToMaxNDigits ( char * number , int index );  
void PrintNumber ( char * number );  
 
void main ()  
{  
    PrintMaxNDigits ( 2 );  
}  
  
//n 位上的 0-9 的全排列问题   
void PrintMaxNDigits ( int n )  
{  
    if ( n <= 0 )  
        return ;  
    char * number = new char [ n + 1 ];  
    number [ n ]= '\0' ;   //末尾,用字符串时,高位在前,低位在后存
 
    PrintToMaxNDigits ( number ,0 );  //已修改,比之前更简洁 
 
    delete [] number ;  
}  
 
// 递归的过程  
void PrintToMaxNDigits ( char * number , int index )  
{  
    int len = strlen ( number );   //这里有冗余,len是定值,不需要每次都算,可修改
    if ( index == len - 1 ) // 递归终止条件  
    {  
        PrintNumber ( number ); // 打印出当前的数字  
        return ;  
    }  
    for ( int i = 0 ; i < 10 ; i ++)  //递归分支,当前数取0~9 
    {  
        number [ index ]= i + '0' ;  
        PrintToMaxNDigits ( number , index + 1 );  //递归深度
    }  
}  
 
// 输出  
void PrintNumber ( char * number )  
{  
    int len = strlen ( number );  
    bool tag = true ;  
    for ( int i = 0 ; i < len ; i ++)  
    {  
        if ( tag && number [ i ]!= '0' ) // 高位为 0 的不输出  
            tag = false ;  
        if (! tag )  
            cout << number [ i ];  
    }  
    if (! tag )  
        cout << endl ;  
}  
 
拓展: 定义一个函数,实现任意两个整数的加法。 由于没有限定输入两个数的大小范围 ,我们也要把它当做大数问题来处理。同样采用字符串来保存加数。

 

posted @ 2019-01-06 17:20 wikiwen 阅读( ...) 评论( ...) 编辑 收藏
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值