日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#刷遍Leetcode面试题系列连载(2): No.38 - 报数

發布時間:2023/12/4 C# 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#刷遍Leetcode面试题系列连载(2): No.38 - 报数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

前文傳送門:

上篇文章中我們主要科普了刷 LeetCode 對大家的作用,今天咱們就正式進行 LeetCode 算法題分析。很多人都知道計算機中有種思想叫?遞歸,相應地也出現了很多算法。解決遞歸問題的要點有如下幾個:

  • 找出遞歸的關系

    比如,給個數列 f(n),常見的遞歸關系是后面的項 f(n+1)與前面幾項之間的關系,比如斐波那契數列的遞歸關系為: f(n+1) = f(n-1) + f(n)

  • 進行遞歸調用

  • 把握好遞歸出口

但實際情況下,遞歸算法的復雜度比較難用數學公式來描述,自由度太大,我們常常需要將遞歸算法優化成迭代(非遞歸)的算法。

今天我們來分析一個遞歸描述的字符串問題,后面我們會給出相應的 非遞歸?算法。

今天要給大家分析的面試題是 LeetCode 上第?38?號問題,

LeetCode - 38. 報數

https://leetcode-cn.com/problems/count-and-say/

題目描述

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

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

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

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

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

示例 1:

輸入: 1 輸出: "1"

示例 2:

輸入: 4 輸出: "1211"

  • 貢獻者: LeetCode

  • 題目難度: Easy

  • 通過率: 52.67%

相關話題

  • 字符串

    https://leetcode.com/tag/string

相似題目

  • 字符串的編碼與解碼

    https://leetcode-cn.com/problems/encode-and-decode-strings/

    難度: 中等

  • 壓縮字符串

    https://leetcode-cn.com/problems/string-compression/

    難度:簡單

解題思路:

首先,這個題按題目描述來看并不是很容易理解。

一句話解釋清楚就是: 第 n+1個字符串是第 n個字符串的讀法,所以這個數列的每一項可列舉如下:

① 1

② 11

③ 21

④ 1211

⑤ 111221

⑥ 312211

...

而讀上一個字符串也是有要求的,就是統計連續出現的字符數量,一旦出現新字符就重新開始統計。

于是最后的結果為: count1 digit1 count2 digit2 ... count n digit n (去掉其中的空格)

接下來,我們該考慮下代碼該怎么寫了。我們在文章開頭提到了下面會才有非遞歸的思路來做,具體可以這么做:

  • 首先我們有個基準,就是第一項?f(n)?= 1

  • 有了第1項,后面每一項只與它之前的項滿足明確的關系,于是想推算出第n項目,我們需要迭代 n-1 次

  • 想辦法獲得每一段 count i digit i 拼接串,從左向右順序掃描之即可,遇到相同的數字計數器+1,遇到不同的置為1重新累加

  • 拼接每一段 count i digit i 字符串,作為輸入進行下一輪迭代

AC的代碼為:

public class Solution { public string CountAndSay(int n) { if (n == 1) return "1"; string res = "1"; for (int i = 0; i < n - 1; i++) // 只需迭代n-1次是因為數列第一個數f(1)已知為 1 { StringBuilder buffer = new StringBuilder(); char currentChar = default(char); int currentCharCount = 0; currentChar = res[0]; foreach (var ch in res) // res用作pre(數列前一項) { if (ch == currentChar) currentCharCount++; else { buffer.Append(currentCharCount.ToString()).Append(currentChar); /* 一旦遇到不同的數字,就追加到拼接字符串 */ currentChar = ch; currentCharCount = 1; } } buffer.Append(currentCharCount.ToString()).Append(currentChar); /* 把最后一個數字及它的數量加上 */ res = buffer.ToString(); // 更新res,用作post(數列后一項) } return res; } }

運行結果:

執行用時 : 100ms, 在所有 C# 提交中擊敗了 97.58%的用戶

代碼要點:

  • 字符串比較常見的拼接方式是使用?+,但頻繁拼接會降低運行速度,比較快的方式是使用?StringBuilder進行拼接,最后用個?ToString()函數即可

  • 注意最后要將最后一個數字及它的數量加上

相應的,如需測試,本地可執行的代碼為:

using System; using System.Text; namespace leetcode38 { public class Solution { public string CountAndSay(int n) { if (n == 1) return "1"; string res = "1"; for (int i = 0; i < n - 1; i++) { StringBuilder buffer = new StringBuilder(); char currentChar = default(char); int currentCharCount = 0; currentChar = res[0]; foreach (var ch in res) { if (ch == currentChar) currentCharCount++; else { buffer.Append(currentCharCount.ToString()).Append(currentChar); currentChar = ch; currentCharCount = 1; } } buffer.Append(currentCharCount.ToString()).Append(currentChar); res = buffer.ToString(); } return res; } public static void Main() { var sol = new Solution(); Console.WriteLine(sol.CountAndSay(8)); } } }

相應代碼已經上傳到github:

https://github.com/yanglr/Leetcode-CSharp/tree/master/leetcode38

參考資料:

https://www.cnblogs.com/TenosDoIt/p/3776356.html

End



你點的每一個"在看"

我都當成了喜歡!

總結

以上是生活随笔為你收集整理的C#刷遍Leetcode面试题系列连载(2): No.38 - 报数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。