[Lc]面试题17打印从1到最大的n位数
Contents
题目
题解
这道题如果不考虑大数的话很简单,但是原书主要是解决输出大数的问题,因此大数也要加以练习(leetcode不考虑大树也能通过)
1. 普通解法
最普通的解法,就是先算上限,然后挨个输出,这种答案不严谨的。
- 时间复杂度$O(10^{n})$
- 空间复杂度$O(10^{n})$
class Solution {
public:
vector<int> printNumbers(int n) {
vector<int> res;
if(n==0) return res;
for(int i=1, k=pow(10,n); i<k; ++i){
res.push_back(i);
}
return res;
}
};
2. char法(书上的)
用char辅助递增和打印数组。下面的几个方法主要是解决大数的问题,即不使用变量存值,而是用string或者char存值挨个输出数字 char的方法见(https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/solution/c-3chong-jie-fa-by-xdb/)
3. string法(书上的改为用string)
class Solution {
vector<int> res;
public:
bool Increment(string& number){
bool isOverflow = false;//判断是否溢出
int takeOver = 0;//进位位
for(int i=number.size()-1; i>=0; --i){
int nSum = number[i] - '0' + takeOver;//每一位先计算出其加上进位后的值
if(i == number.size()-1) nSum++;//最低为加1
if(nSum >= 10){
if(i==0) isOverflow = true;//最高位有进位,溢出位置true
else{//非最高位有进位,改变这个数位当前累加和-10,再把进位位置true
number[i] = nSum - 10 + '0';
takeOver = 1;
}
}else{
number[i] = nSum + '0';
break;//如果没有进位,那么改变完最后一个有进位的数就可以跳出循环。高位的数不需要改变
}
}
return isOverflow;
}
////两种savenumber的写法,第二种更简洁
// void saveNumber(string number){
// string new_number;
// bool isBegin0 = true;
// for(auto& n: number){
// if(isBegin0 && n != '0') isBegin0 = false;
// if(!isBegin0){
// new_number.push_back(n);
// }
// }
// //对于本题以上都没用,上面是用来去掉前面的0的
// int num = stoi(new_number);
// res.emplace_back(num);
// }
void saveNumber(const string& number)
{
auto index = number.find_first_not_of('0');//找到第一个不0的字符小标
if(index!=string::npos)//若全为0则返回string::npos
res.push_back(stoi(number.substr(index)));
}
vector<int> printNumbers(int n) {
if(n==0) return res;
string number(n,'0');//初始化number,n个0
while(!Increment(number)){
saveNumber(number);
}
return res;
}
};
4. 递归法
class Solution {//四种方法。4.递归
vector<int> res;
public:
void permutation(string& number, int length, int index){
if(index == length){
saveNumber(number);
return;
}//当index超出界限,就在res中保存,并返回
//没超出,就不断递归,每一位index有十个数i
for(int i=0; i<10; ++i){
number[index] = i + '0';//这一步是给当前位赋值
permutation(number, length, index+1);//然后递归下一位
}
}
void saveNumber(string& number){
//这是为了跳过0这个数,当其全为0的时候不save
string tmp_number(number.size(), '0');
if(tmp_number != number){
res.push_back(stoi(number));
}
}
vector<int> printNumbers(int n) {
if(n==0) return res;
string number(n,'0');//初始化number,n个0
permutation(number, n, 0);//调用递归函数进行全排列
return res;
}
};
Author ChrisHRZ
LastMod 2020-05-13