基礎知識要求:
Java:方法、for循環、if eles語句、StringBuilder類
Python: 方法、for循環、if else語句、字符串拼接
題目:?
「外觀數列」是一個數位字符串序列,由遞歸公式定義:
countAndSay(1) = "1"
countAndSay(n)
?是?countAndSay(n-1)
?的行程長度編碼。
行程長度編碼(RLE)是一種字符串壓縮方法,其工作原理是通過將連續相同字符(重復兩次或更多次)替換為字符重復次數(運行長度)和字符的串聯。例如,要壓縮字符串?"3322251"
?,我們將?"33"
?用?"23"
?替換,將?"222"
?用?"32"
?替換,將?"5"
?用?"15"
?替換并將?"1"
?用?"11"
?替換。因此壓縮后字符串變為?"23321511"
。
給定一個整數?n
?,返回?外觀數列?的第?n
?個元素。
示例 1:
輸入:n = 4
輸出:"1211"
解釋:
countAndSay(1) = "1"
countAndSay(2) = "1" 的行程長度編碼 = "11"
countAndSay(3) = "11" 的行程長度編碼 = "21"
countAndSay(4) = "21" 的行程長度編碼 = "1211"
示例 2:
輸入:n = 1
輸出:"1"
解釋:
這是基本情況。
提示:
1 <= n <= 30
思路解析:
- 理解問題:
- 首先,理解外觀數列的定義。它從一個單獨的字符 "1" 開始,后續每一項都是對前一項的行程長度編碼(RLE)。
- 行程長度編碼(RLE)是將連續的相同字符替換為它們出現的次數和該字符的串聯。
- 初始化:
- 對于基本情況,即?
n = 1
,直接返回字符串 "1"。 - 對于其他情況,我們需要一個循環來迭代地從?
n = 2
?構建到?n
。
- 對于基本情況,即?
- 迭代構建:
- 在循環中,我們需要兩個變量:一個是?
prev
(存儲前一項的外觀數列),初始化為 "1";另一個是?curr
(存儲當前項的外觀數列),初始化為空字符串。 - 還需要一個變量?
count
?來跟蹤?prev
?中連續相同字符的數量,初始化為 1。 - 遍歷?
prev
?字符串,每次迭代時檢查當前字符與前一個字符是否相同。如果相同,count
?加 1;如果不同,將?count
?和前一個字符添加到?curr
?中,并重置?count
?為 1。 - 在遍歷完?
prev
?后,別忘了處理最后一個字符的計數,因為循環中可能沒有捕獲到它。 - 最后,將?
curr
?設置為新的?prev
,以便下一次迭代。
- 在循環中,我們需要兩個變量:一個是?
- 返回結果:
- 當循環結束時,
prev
?將包含外觀數列的第?n
?個元素。 - 返回?
prev
?即可。
- 當循環結束時,
- 編寫代碼:
- 根據上述思路,編寫代碼實現外觀數列的生成。
這樣,我們就可以通過迭代的方式構建出外觀數列,并返回第?n
?個元素。
Java代碼示例:
public class CountAndSay { public String countAndSay(int n) { if (n == 1) { return "1"; } String prev = "1"; // 外觀數列的前一項 for (int i = 2; i <= n; i++) { StringBuilder curr = new StringBuilder(); // 當前項,使用StringBuilder更高效 int count = 1; // 連續字符的計數 // 遍歷前一項字符串 for (int j = 1; j < prev.length(); j++) { if (prev.charAt(j) == prev.charAt(j - 1)) { count++; // 連續字符,計數加1 } else { // 字符不連續,將前一個字符的計數和字符本身添加到當前項中 curr.append(count).append(prev.charAt(j - 1)); count = 1; // 重置計數 } } // 處理最后一個字符的計數 curr.append(count).append(prev.charAt(prev.length() - 1)); // 更新前一項為當前項 prev = curr.toString(); } // 返回外觀數列的第n個元素 return prev; } public static void main(String[] args) { CountAndSay solution = new CountAndSay(); System.out.println(solution.countAndSay(4)); // 輸出: 1211 System.out.println(solution.countAndSay(1)); // 輸出: 1 }
}
Python代碼示例:
def countAndSay(n: int) -> str: if n == 1: return "1" prev = "1" # 初始化prev為外觀數列的第一個元素 for i in range(2, n + 1): curr = "" # 用于構建當前外觀數列元素的字符串 count = 1 # 初始化計數為1,用于計算連續字符的數量 # 遍歷prev字符串,統計連續字符的數量并構建curr字符串 for j in range(1, len(prev)): if prev[j] == prev[j - 1]: count += 1 else: curr += str(count) + prev[j - 1] # 將前一個字符的計數和字符本身添加到curr中 count = 1 # 重置計數 # 處理最后一個字符的計數 curr += str(count) + prev[-1] # 更新prev為curr,以便下一次迭代 prev = curr return prev # 示例
print(countAndSay(4)) # 輸出: "1211"
print(countAndSay(1)) # 輸出: "1"