天天看點

<LeetCode天梯>Day022 外觀數列(遞歸+雙指針) | 初級算法 | Python

以下為我的天梯積分規則:

每日至少一題:一題積分+10分

若多做了一題(或多一種方法解答),則當日積分+20分(+10+10)

若做了三道以上,則從第三題開始算+20分(如:做了三道題則積分-10+10+20=40;做了四道題則積分–10+10+20+20=60)

初始分為100分

若差一天沒做題,則扣積分-10分(周六、周日除外注:休息)

堅持!!!

初級算法

刷題目錄

字元串

<LeetCode天梯>Day022 外觀數列(遞歸+雙指針) | 初級算法 | Python
<LeetCode天梯>Day022 外觀數列(遞歸+雙指針) | 初級算法 | Python

題幹

給定一個正整數 n ,輸出外觀數列的第 n 項。

「外觀數列」是一個整數序列,從數字 1 開始,序列中的每一項都是對前一項的描述。

你可以将其視作是由遞歸公式定義的數字字元串序列:

countAndSay(1) = “1”

countAndSay(n) 是對 countAndSay(n-1) 的描述,然後轉換成另一個數字字元串。

前五項如下:

<LeetCode天梯>Day022 外觀數列(遞歸+雙指針) | 初級算法 | Python

要 描述 一個數字字元串,首先要将字元串分割為 最小 數量的組,每個組都由連續的最多 相同字元 組成。然後對于每個組,先描述字元的數量,然後描述字元,形成一個描述組。要将描述轉換為數字字元串,先将每組中的字元數量用數字替換,再将所有描述組連接配接起來。

例如,數字字元串 “3322251” 的描述如下圖:

<LeetCode天梯>Day022 外觀數列(遞歸+雙指針) | 初級算法 | Python

示例1:

輸入:n = 1

輸出:“1”

解釋:這是一個基本樣例。

示例2:

輸入:n = 4

輸出:“1211”

解釋:

countAndSay(2) = 讀 “1” = 一 個 1 = “11”

countAndSay(3) = 讀 “11” = 二 個 1 = “21”

countAndSay(4) = 讀 “21” = 一 個 2 + 一 個 1 = “12” + “11” = “1211”

提示:

1 <= n <= 30

遞歸法+雙指針

分析:

根據上面的規則,輸入的是n,輸出第n次描述,也就是描述上一層的數字。

這裡得用上遞歸的思想,每一次都進行疊代,然後根據輸入的n,作為停止的判斷,然後直接輸出目前層的描述。

依次讀取上一層,先對每一個字元進行索引,判斷是否相同,直到不同,記下相同的個數用于描述,再繼續讀取,讀到不同,則停止,每次不同都停止,切片,然後做計算,最後再描述。遞歸此過程。

需要先定義好出口,當n=1時,輸出為1.

class Solution:
    def countAndSay(self, n: int) -> str:
    if n == 1:
        return "1"      # 設定遞歸出口

    # 假設我們上一層的結果為“112213”
    s1 = countAndSay(n-1)  # 遞歸
    res = ''    # 設定新串
    slow = 0       # 慢指針
    fast = 1       # 快指針
    s1 += '0'      # 末尾标志,因為不會出現0
    while fast < len(s1):
        if s1[slow] != s1[fast]:                    # 判斷是否數字相同
            res += str(fast-slow) + str(s1[slow])   # 前半部分表示後半部分的個數
            slow = fast                             # 遇到不同,将快指針位置指派給慢指針
        fast += 1                                   

    return res      
<LeetCode天梯>Day022 外觀數列(遞歸+雙指針) | 初級算法 | Python