Loading

剑指 Offer 17. 打印从1到最大的n位数

 

思路

(1) 不考虑n很大的情况

 1 class Solution {
 2 public:
 3     vector<int> printNumbers(int n) {
 4         vector<int> res;
 5         int m = 1;
 6         for(int i = 0; i < n; ++i) 
 7             m = m*10;
 8         
 9         for(int i = 1; i < m; ++i) 
10             res.push_back(i); 
11         
12         return res;
13     }
14 };

 

(2) 考虑n很大的情况

  方法一:使用字符串模拟数字的加法

 

 

 1 bool increment(string& num); 
 2 void printNumber(const string& num);
 3 
 4 int main()
 5 {
 6     int n;
 7     cin >> n;
 8     string maxNum(n, '9');
 9     string num(n, '0');
10     while(!increment(num)) {    //使用了O(1)时间判断是否已经自增到了最大值 
11         printNumber(num);
12         printf("\t");
13     }
14 
15     return 0;
16 }
17 
18 //自增1
19 //使用了O(1)时间判断是否已经自增到了最大值 
20 bool increment(string& num) {
21     bool isHighestBitCarry = false; //最高位是否进位
22     int numLen = num.length();
23     int carry = 0;  //进位
24 
25     for(int i = numLen-1; i >= 0; --i) {
26         int x = num[i] -'0' + carry;
27         carry = 0;
28         if(i == numLen-1) {
29             x += 1;
30         }
31         
32         if(x >= 10) {
33             carry++;    //产生进位
34             if(i == 0)
35                 isHighestBitCarry = true;
36             x -= 10;
37         } 
38 
39         num[i] = '0' + x;
40     }
41     
42     return isHighestBitCarry;
43 }
44 
45 
46 //打印的时候消去前置0 
47 void printNumber(const string& num) {
48     bool isBeginWith0 = true;
49     for(int i = 0; i < num.length(); ++i) {
50         if(num[i] != '0')
51             isBeginWith0 = false;
52         if(!isBeginWith0)
53             printf("%c", num[i]);
54     }
55 }

 

  方法二:把问题转换成数字排列的解法

 

 

 1 void printNumber(const string& num);
 2 void dfs(string& num, int n, int step);
 3 
 4 int main()
 5 {
 6     int n;
 7     cin >> n;
 8     string num(n, '0');
 9     dfs(num, n, 0);
10 
11     return 0;
12 }
13 
14 //递归打印数字排列 
15 void dfs(string& num, int n, int step) {
16     if(step == n) {
17         printNumber(num);
18         printf("\t");
19         return;
20     }
21     
22     for(int i = 0; i < 10; ++i) {
23         num[step] = '0' + i;
24         dfs(num, n, step+1);
25     }
26 }
27 
28 //打印的时候消去前置0
29 void printNumber(const string& num) {
30     bool isBeginWith0 = true;
31     for(int i = 0; i < num.length(); ++i) {
32         if(num[i] != '0')
33             isBeginWith0 = false;
34         if(!isBeginWith0)
35             printf("%c", num[i]);
36     } 
37 }

 

复杂度分析

 

参考

《剑指offer(第2版)》- 面试题17:打印从1到最大的n位数

posted @ 2020-10-23 08:58  拾月凄辰  阅读(116)  评论(0编辑  收藏  举报