剑指offer 面试题17:打印从1到最大的n位数

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;
	}
};

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值