【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
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 阅读(
...) 评论(
...) 编辑 收藏