1.题目
输入数字n,按顺序打印出从1到最大的n位十进制数,比如输入3,则打印1到999。
2.思路
2.1思路1
n位所有十进制数其实就是n个从0到9的全排列。
2.2思路2
模拟字符串加法的操作。
3.实现
3.1 思路1的实现
class Solution {
public:
void Print1ToMaxOfNDigits(int n)
{
char* number = new char[n + 1];
//开辟一个存放字符数组(包含n + 1个元素 number[0]~number[n])的空间,返回字符数组首元素的地址
memset(number, '0', n); // number[0]~number[n-1]都是'0'
number[n] = '\0';
dfsHelper(number, 0, n);
}
private:
void PrintNumber(char* number) //此函数用于打印数字,数字前面补位的“0”不打印
{
bool isBeginning0 = true;
int nLength = strlen(number);
for (int i = 0; i < nLength; i++)
{
if (isBeginning0 && number[i] != '0')//开始不为0,第i位不是0
isBeginning0 = false; //例如“00098”到number[2]才不是0,两个条件都为true
//isBeginning0 = false
if (!isBeginning0) //isBeginning0 = false才能执行输出
cout << number[i];
}
cout << endl;
}
void dfsHelper(char* number, int index, int n)
{
if (index == n)
{
PrintNumber(number);
return;
}
for (int i = 0; i < 10; i++)
{
number[index] = i + '0';
dfsHelper(number, index + 1, n);
}
}
};
3.2思路2的实现
class Solution {
public:
void Print1ToMaxOfNDigits(int n)
{
char* number = new char[n + 1];
//开辟一个存放字符数组(包含n + 1个元素 number[0]~number[n])的空间,返回字符数组首元素的地址
memset(number, '0', n); // number[0]~number[n-1]都是'0'
number[n] = '\0';
while (!Increment(number))
{
PrintNumber(number);
}
}
private:
bool Increment(char* number)
{
//此函数用于在表示数字的字符串上 + 1,并判断有没有溢出
//number是一个字符串
bool isOverflow = false; //溢出
int nTackOver = 0; //进位标志
int nLength = strlen(number); //计算字符串str 的长度,直到空结束字符
// number[nLength - 1]是这个数字的倒数第1位
for (int i = nLength - 1; i >= 0; i--)
{
int nSum = number[i] - '0' + nTackOver;
if (i == nLength - 1)
nSum++; //如果是个位(最后一位)的话,+1
if (nSum >= 10)
if (i == 0)
isOverflow = true; //如果nSum==10,且是最高位,则溢出
else
{
nSum -= 10;
nTackOver = 1; //进位
number[i] = '0' + nSum;
}
else
{
number[i] = '0' + nSum;
break; //运行到某一数位不需要进位,退出循环
// 例如520+1之后个位 nSum < 10,此时不会产生进位,也不会有溢出的情况
//可以直接退出循环
}
}
return isOverflow;
}
void PrintNumber(char* number) //此函数用于打印数字,数字前面补位的“0”不打印
{
bool isBeginning0 = true;
int nLength = strlen(number);
for (int i = 0; i < nLength; i++)
{
if (isBeginning0 && number[i] != '0')//开始不为0,第i位不是0
isBeginning0 = false; //例如“00098”到number[2]才不是0,两个条件都为true
//isBeginning0 = false
if (!isBeginning0) //isBeginning0 = false才能执行输出
cout << number[i];
}
cout << endl;
}
};