劍指offer | 17. 列印從1到最大的n位數
題目內容:
輸入數字 n,按順序列印出從 1 到最大的 n 位十進位制數。比如輸入 3,則列印出 1、2、3 一直到最大的 3 位數 999。
示例 1:
輸入: n = 1
輸出: [1,2,3,4,5,6,7,8,9]
說明:
用返回一個整數列表來代替列印
n 為正整數
方法一:
- 由觀察可以得出,不超過n位數就是指不超過 1 0 n 10^n 10n,比如n=3,那麼就是不超過1000.
- 又因為題幹中返回的是int,所以說嘛不會越界,那麼最直觀的方法應該是可行的:
class Solution {
public:
vector<int> printNumbers(int n) {
int c=pow(10,n);
vector<int> ans;
if(n==0)return ans;//邊界問題不要忘記
for(int i=1;i<c;i++){
ans.push_back(i);
}
return ans;
}
};
方法二:大數法
- 面試的時候一般不會如此沒有坑的題,很可能會出一個int越界之類的,所以我們必須知道如果越界該怎麼做?
- 大數法就是用字串模擬數字的方法,可以通過將數字轉成字元的形式,避免越界問題。假設n=3,那麼就是定義一個字串,初始化成000,然後從1到n進行加減法,最後存到int中迴圈輸出。
- 字元型
char
轉換成數值型int
,我們可以寫成:int i = c - '0'
- 數值型
int
轉換成字元型char
,我們可以寫成:char c = i + '0'
class Solution {
public:
vector<int> output;
vector<int> printNumbers(int n) {
// 以下注釋的前提:假設 n = 3
if(n <= 0) return vector<int>(0);
string s(n, '0'); // s最大會等於999,即s的長度為n
while(!overflow(s)) output.push_back(stoi(s));
return output;
}
bool overflow(string& s)
{
// 本函式用於模擬數字的累加過程,並判斷是否越界(即 999 + 1 = 1000,就是越界情況)
bool isOverFlow = false;
int carry = 0; // carry表示進位
for(int i=s.length()-1; i>=0; --i)
{
int current = s[i] - '0' + carry; // current表示當前這次的操作
if(i == s.length() - 1) current ++; // 如果i此時在個位,current執行 +1 操作
if(current >= 10)
{
// 假如i已經在最大的那一位了,而current++之後>=10,說明迴圈到頭了,即999 + 1 = 1000
if(i == 0) isOverFlow = true;
else
{
// 只是普通進位,比如current從9變成10
carry = 1;
s[i] = current - 10 + '0';
}
}
else
{
// 如果沒有進位,更新s[i]的值,然後直接跳出迴圈,這樣就可以回去執行inputNumbers函式了,即往output裡新增元素
s[i] = current + '0';
break;
}
}
return isOverFlow;
}
};
- stoi函式預設要求輸入的引數字串是符合int範圍的[-2147483648, 2147483647],否則會runtime error。
- atoi函式則不做範圍檢查,若超過int範圍,則顯示-2147483648(溢位下界)或者2147483647(溢位上界)。
- stoi標頭檔案:,c++函式
- atoi標頭檔案:,c函式
- atoi()的引數是 const char* ,因此對於一個字串str我們必須呼叫 c_str()的方法把這個string轉換成 const char*型別的,
- 而stoi()的引數是const string*,不需要轉化為 const char*;
方法三:遞迴全排列 - 輸出n位數的全排列。
class Solution {
public:
vector<int> output;
vector<int> printNumbers(int n) {
if(n <= 0) return vector<int>(0);
string s(n, '0');
for(int i=0; i<=9; ++i)
{
s[0] = i + '0';
permutation(s, s.length(), 1);
}
return output;
}
void permutation(string& s, int length, int pos)
{
if(pos == length)
{
inputNumbers(s);
return;
}
for(int i=0; i<=9; ++i)
{
s[pos] = i + '0';
permutation(s, length, pos + 1);
}
}
void inputNumbers(string s)
{
bool isUnwantedZero = true;// 判斷是否是不需要新增的0,比如001前面的兩個0
string temp = "";
for(int i=0; i<s.length(); ++i)
{
if(isUnwantedZero && s[i] != '0') isUnwantedZero = false;
if(!isUnwantedZero) temp += s[i];
}
if(temp != "") output.push_back(stoi(temp)); // 如果 s = "000",則temp會是空,stoi無法執行,會報錯
}
};
相關文章
- 【劍指 Offer 】17. 列印從1到最大的n位數
- 劍指 Offer 列印從1到最大n位數c++C++
- 劍指Offer-17-列印從1到最大的n位數-Java程式碼實現(兩種思路)Java
- LeetCode題解(Offer17):列印從1到最大的n位數(Python)LeetCodePython
- JZ-068-列印從 1 到最大的 n 位數
- offer通過--12列印1到最大的n的的位數-2
- [每日一題] 第二十四題:列印從1到最大的n位數每日一題
- 【Algorithm】《劍指offer》面試題32----從1到n整數中1出現的次數Go面試題
- 3. 從尾到頭列印連結串列(劍指offer)
- 劍指offer-從尾到頭列印連結串列-phpPHP
- 【劍指offer】二進位制中1的個數
- 劍指 Offer 15. 二進位制中1的個數
- 力扣 - 劍指 Offer 06. 從尾到頭列印連結串列.md力扣
- 劍指OFFER-從頭到尾列印連結串列(Java)Java
- 【劍指offer中等部分4】二進位制中1的個數(java)Java
- 劍指offer之順序列印陣列陣列
- 劍指offer——從上往下列印二叉樹C++二叉樹C++
- 劍指offer之列印超過陣列一半的數字陣列
- 劍指offer:輸入n個整數,找出其中最小的K個數。
- 1. 二位陣列中的查詢(劍指offer)陣列
- 劍指 Offer 53 - II. 0~n-1中缺失的數字(二分法)1
- 劍指 Offer 32 - III. 從上到下列印二叉樹 III二叉樹
- 劍指offer(java實現)第3題“從尾到頭列印連結串列”-牛客網Java
- 劍指Offer 表示數值的字串字串
- 劍指 offer(1) -- 陣列篇陣列
- 53. 最大子序和(劍指 Offer 42)
- 劍指 Offer 44. 數字序列中某一位的數字
- 劍指offer-19:順時針列印矩陣矩陣
- [劍指offer] 把二叉樹列印成多行二叉樹
- LeetCode 劍指offer——從上到下列印二叉樹 II、從上到下列印二叉樹 IIILeetCode二叉樹
- 劍指OFFER
- leetcode *劍指 Offer 47. 禮物的最大價值LeetCode
- 劍指offer(59)——滑動視窗的最大值
- 劍指Offer 47. 禮物的最大價值(Medium)
- 劍指 Offer 59 - II. 佇列的最大值佇列
- 【劍指offer】5.二叉樹的映象和列印二叉樹
- LeetCode C++ 劍指 Offer 64. 求1+2+…+n【Bit Manipulation】中等LeetCodeC++
- 劍指 Offer 32 - I. 從上到下列印二叉樹(java解題)二叉樹Java