目录

前言

前文传送门:

C# 刷遍 Leetcode 面试题系列连载(1) - 入门与工具简介

系列教程索引

地址:https://enjoy233.cnblogs.com/articles/leetcode_csharp_index.html

  1. C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介
  2. C#刷遍Leetcode面试题系列连载(2): No.38 - 报数
  3. C# 刷遍 Leetcode 面试题系列连载(3): No.728 - 自除数

上篇文章中我们主要科普了刷 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" ( "一个一") , 即 11。11 被读作 "two 1s" ( "两个一"), 即 21。21 被读作 "one 2", " one1" ( "一个二" , "一个一") , 即 1211。

给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。

注意:整数顺序将表示为一个字符串。

示例 1:

输入: 1
输出: "1"

示例 2:

输入: 4
输出: "1211"
  • 贡献者: LeetCode

  • 题目难度: Easy

  • 通过率: 52.67%

相关话题

相似题目

解题思路:

首先,这个题按题目描述来看并不是很容易理解。

一句话解释清楚就是: 第 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++) // 只需迭代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;
} 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


作者简介:Bravo Yeung,计算机硕士,知乎干货答主(获81K 赞同, 38K 感谢, 235K 收藏)。曾在国内 Top3互联网视频直播公司工作过,后加入一家外企做软件开发至今。

如需转载,请加微信 iMath7 申请开白!

欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。

欢迎各位读者加入 .NET技术交流群,在公众号后台回复“加群”或者“学习”即可。

文末彩蛋

微信后台回复“asp”,给你:一份全网最强的ASP.NET学习路线图。



回复“cs”,给你:一整套 C# 和 WPF 学习资源!



回复“core”,给你:2019年dotConf大会上发布的.NET core 3.0学习视频!

C#刷遍Leetcode面试题系列连载(2): No.38 - 报数的更多相关文章

  1. C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介

    目录 为什么要刷LeetCode 刷LeetCode有哪些好处? LeetCode vs 传统的 OJ LeetCode刷题时的心态建设 C#如何刷遍LeetCode 选项1: VS本地Debug + ...

  2. C#刷遍Leetcode面试题系列连载(4) No.633 - 平方数之和

    上篇文章中一道数学问题 - 自除数,今天我们接着分析 LeetCode 中的另一道数学题吧~ 今天要给大家分析的面试题是 LeetCode 上第 633 号问题, Leetcode 633 - 平方数 ...

  3. C#刷遍Leetcode面试题系列连载(5):No.593 - 有效的正方形

    上一篇 LeetCode 面试题中,我们分析了一道难度为 Easy 的数学题 - 自除数,提供了两种方法.今天我们来分析一道难度为 Medium 的面试题. 今天要给大家分析的面试题是 LeetCod ...

  4. C# 刷遍 Leetcode 面试题系列连载(3): No.728 - 自除数

    前文传送门: C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介 C#刷遍Leetcode面试题系列连载(2): No.38 - 报数 系列教程索引 传送门:https://enjoy2 ...

  5. C#刷遍Leetcode系列连载 索引

    C#刷遍Leetcode系列文章 索引 索引(陆续发布中,请保持关注) C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介 C#刷遍Leetcode面试题系列连载(2): No.38 - ...

  6. .NET面试题系列[0] - 写在前面

    .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] - .NET框架基础知识(2) .NET面试题系列[3] - C# 基础知识(1) .NET ...

  7. 【转载】.NET面试题系列[0] - 写在前面

    原文:.NET面试题系列[0] - 写在前面 索引: .NET框架基础知识[1] - .NET框架基础知识(1) http://www.cnblogs.com/haoyifei/p/5643689.h ...

  8. .NET面试题系列

    索引: .NET框架基础知识[1] - http://www.cnblogs.com/haoyifei/p/5643689.html .NET框架基础知识[2] - http://www.cnblog ...

  9. Java容器--2021面试题系列教程(附答案解析)--大白话解读--JavaPub版本

    Java容器--2021面试题系列教程(附答案解析)--大白话解读--JavaPub版本 前言 序言 再高大上的框架,也需要扎实的基础才能玩转,高频面试问题更是基础中的高频实战要点. 适合阅读人群 J ...

随机推荐

  1. Codeforces 734D. Anton and Chess(模拟)

    Anton likes to play chess. Also, he likes to do programming. That is why he decided to write the pro ...

  2. yzoj1985 最长公共单调上升子序列 题解

    题面给两个序列a,b长度分别为n,m求最长公共上升子序列,百度了一下求公共子序列的问题好像叫做LCS,而上升的叫做LCIS.都是dp的例题. 先来说说最长公共子序列,这是一道比较经典的dp题,我们可以 ...

  3. 【Nginx】实现负载均衡的几种方式

    要理解负载均衡,必须先搞清楚正向代理和反向代理. 注: 正向代理,代理的是用户. 反向代理,代理的是服务器 什么是负载均衡 当一台服务器的单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能 ...

  4. 使用xampp将angular项目运行在web服务器

    需求 在开发angular项目时,因为需要做自适配以适应不同的屏幕,而我的电脑只有1366的.所以我现在需要在本地将angular项目运行在xampp上,然后用手机开热点,给本机和另一台大屏电脑或手机 ...

  5. ELKBR部署检测项目日志

    ELK filebeat:具有日志收集功能,相比logstash,+filebeat更轻量,占用资源更少,适合客户端使用. redis消息队列选型:Redis 服务器通常都是用作 NoSQL 数据库, ...

  6. JSP静态include和动态include的区别

    静态include是指令元素.include指令的语法格式:<%@ include file="filename" %>.include指令的作用是在JSP页面中静态包 ...

  7. cssrelative

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. Spring Boot 利用 nginx 实现生产环境的伪热更新

    当我们在服务器部署Java程序,特别是使用了 Spring Boot 生成单一 Jar 文件部署的时候,单一文件为我们开发单来的极大的便利性,保障程序的完整性.但同时对我们修改程序中的任何一处都带来重 ...

  9. Winforn中DevExpress的TreeList中显示某路径下的所有目录和文件(附源码下载)

    场景 Winform中DevExpress的TreeList的入门使用教程(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  10. LinkedHashSet集合

    LinkedHashSet集合与HashSet集合的最大区别在于,LinkedHashSet集合存入和取出的顺序相同,而HashSet集合存取顺序不一定相同: import java.util.Has ...