描述:java
報數序列是一個整數序列,按照其中的整數的順序進行報數,獲得下一個數。其前五項以下:編程
1. 1 2. 11 3. 21 4. 1211 5. 111221
1
被讀做 "one 1"
("一個一"
) , 即 11
。 11
被讀做 "two 1s"
("兩個一"
), 即 21
。 21
被讀做 "one 2"
, "one 1"
("一個二"
, "一個一"
) , 即 1211
。app
給定一個正整數 n(1 ≤ n ≤ 30),輸出報數序列的第 n 項。函數
注意:整數順序將表示爲一個字符串。ui
示例 1:spa
輸入: 1 輸出: "1"
示例 2:code
輸入: 4 輸出: "1211"
思路:遞歸
報數,按題目意思就是讀取上一個數字,「報」上一個數字,好比 1 讀做 「one 1 」,即下一個數就是 11(「one 1」) ,讀出來上一個數。同理,11 讀做 」two 1s「,表明兩個一,那麼下一個數讀出來即 21(two 1s),s不用讀,連着一塊兒的數字會先說數量再說值。21 讀做 」one 2 one 1「,因此下一個數讀出來爲 1211。這即是報數。字符串
理解了報數什麼含義,那麼接下來咱們就來編寫代碼。報數的話有點像斐波那契數列,都是根據以前的結果,獲得以後的結果,因此能夠用迭代的思惟,初定初始值(即第一個數)爲 1,從原來的值不斷推出新值。咱們從前日後遍歷字符串,統計相同數字的個數,把 a 個 b 寫成 ab 的形式,依次統計出全部數字,鏈接在一塊兒即是咱們推出的下一個數了。依次類推,又根據前面的數利用一樣的規律再推出新數。io
代碼以下:
class Solution { public String countAndSay(int n) { String oldString = "1"; while (--n > 0) { StringBuilder countSay = new StringBuilder(); for (int i = 0; i < oldString.length(); i++) { int count = 1; while ((i+1) < oldString.length() && oldString.charAt(i) == oldString.charAt(i+1)) { count++; i++; } countSay.append(String.valueOf(count) + String.valueOf(oldString.charAt(i))); } oldString = countSay.toString(); } return oldString; } }
擴展:遞歸和迭代的區別
遞歸
遞歸:程序調用自身的編程技巧稱爲遞歸,是函數本身調用本身。
使用遞歸要注意的有兩點:
1)遞歸就是在過程或函數裏面調用自身;
2)在使用遞歸時,必須有一個明確的遞歸結束條件,稱爲遞歸出口。
迭代
迭代:利用變量的原值推算出變量的一個新值。若是遞歸是本身調用本身的話,迭代就是A不停的調用B。
區別與聯繫
遞歸中必定有迭代,可是迭代中不必定有遞歸,大部分能夠相互轉換。能用迭代的不用遞歸,遞歸調用函數,浪費空間,而且遞歸太深容易形成堆棧的溢出。