LeetCode 38. 報數

38. 報數

難度:簡單java

題庫地址:leetcode-cn.com/problems/re…算法

這道題算法不難,難的是讀懂題😂,下面會說一下這道題到底要幹嗎bash

1. 題目描述

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

1.     1
2.     11
3.     21
4.     1211
5.     111221
複製代碼

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

給定一個正整數 n(1 ≤ n ≤ 30,輸出報數序列的第 n 項。spa

注意:整數順序將表示爲一個字符串。.net

示例 1:code

輸入: 1
輸出: "1"
複製代碼

示例 2:cdn

輸入: 4
輸出: "1211"
複製代碼

2. 解題思路

讀完題一臉懵逼,在讀一遍仍是一臉懵逼,讀了幾遍才知道要幹嗎。blog

這道題實際上是給定一個正整數 n(1 ≤ n ≤ 30,找到這項對應的報數序列。

  • 怎麼找?答案是根據這個 n 的前一項進行報數
  • 怎麼報數?從左往右,遇到相同的數字當作一個總體連在一塊兒讀
    • 好比第 4 項是1211,拆分後能夠看作1``2``11,讀出來就是,111221,將這幾個數字從左到右拼在一塊兒就是111221
    • 好比第 5 項是111221,拆分後能夠看作111``22``1,讀出來就是,312211,將這幾個數字從左到右拼在一塊兒就是312211
  • 要算出當前項的報數序列,就要先算出前一項的報數序列,明顯要用遞歸方法,而遞歸的約束條件就是第 1 項這個初始條件1,初始條件不一樣後續的序列就不一樣

Java實現:

public String countAndSay(int n) {
    if (n == 1) {
        return "1";
    } else {
        String before = countAndSay(n - 1);
        StringBuilder sb = new StringBuilder();
        // 數字分組的依據,記錄當前對那個數字進行分組,默認取第一個
        char c = before.charAt(0);
        // 由於默認取第一個數字做爲分組依據,因此當前組的數字個數已經爲1了
        int count = 1;
        // 從第2個數字開始遍歷(若是字符串長度 > 1)
        for (int i = 1; i < before.length(); i++) {
            char tmp = before.charAt(i);
            if (c == tmp) {
                // 若是當前遍歷數字和分組數字一致,則繼續遍歷,該組個數 +1
                count++;
            } else {
                // 若是當前遍歷數字和分組數字不一致,將分組數字拼接到結果中
                // 從新開始一個分組,注意這裏拼接的已是上一個分組數據了
                // 因此字符串最後一個分組是不會在這裏拼接到最終返回結果中的,只是保存了
                sb.append(count).append(Character.getNumericValue(c));
                c = tmp;
                count = 1;
            }
        }
        // 若是上一個只有一位,根本不會進入for循環,咱們只記錄了表明分組的數字,和個數,還沒拼接到結果中
        // 遍歷到for循環的最後一位數字時,結果只是保存在了 c、count兩個變量中,這裏拼接上
        sb.append(count).append(Character.getNumericValue(c));
        return sb.toString();
    }
}
複製代碼

運行結果以下:

相關文章
相關標籤/搜索