leecode刷題(18)-- 報數

leecode刷題(18)-- 報數

報數

描述:java

報數序列是一個整數序列,按照其中的整數的順序進行報數,獲得下一個數。其前五項以下:編程

1.     1
2.     11
3.     21
4.     1211
5.     111221

1 被讀做 "one 1" ("一個一") , 即 1111 被讀做 "two 1s" ("兩個一"), 即 2121 被讀做 "one 2", "one 1""一個二" , "一個一") , 即 1211app

給定一個正整數 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。

區別與聯繫

遞歸中必定有迭代,可是迭代中不必定有遞歸,大部分能夠相互轉換。能用迭代的不用遞歸,遞歸調用函數,浪費空間,而且遞歸太深容易形成堆棧的溢出。

相關文章
相關標籤/搜索