本文小编为大家详细介绍“Go Java算法之外观数列如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Go Java算法之外观数列如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
给定一个正整数 n ,输出外观数列的第 n 项。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。
你可以将其视作是由递归公式定义的数字字符串序列:
countAndSay(1) = "1"
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
前五项如下:
1、1 —— 第一项是数字 1
2、11 —— 描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"
3、21 —— 描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"
4、1211 —— 描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"
5、111221 —— 描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"
所谓的「外观数列」,其实本质上只是依次统计字符串中连续相同字符的个数。
题目中给定的递归公式定义的数字字符串序列如下:
countAndSay(1) = "1";
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
我们定义字符串 S_{i}表示countAndSay(i),我们如果要求得 S_{n},则我们需先求出 S_{n-1},然后按照上述描述的方法生成,即从左到右依次扫描字符串 S_{n-1}中连续相同的字符的最大数目,然后将字符的统计数目转化为数字字符串再连接上对应的字符。
class Solution { public String countAndSay(int n) { String str = "1"; for (int i = 2; i <= n; ++i) { StringBuilder sb = new StringBuilder(); int start = 0; int pos = 0; while (pos < str.length()) { while (pos < str.length() && str.charAt(pos) == str.charAt(start)) { pos++; } sb.append(Integer.toString(pos - start)).append(str.charAt(start)); start = pos; } str = sb.toString(); } return str; } }
N 为给定的正整数,M 为生成的字符串中的最大长度
时间复杂度:O(N * M)
空间复杂度:O(M)
具体的方法分析已经在上文中表述
由于每次得到的数据都是来源于上一次的结果,所以我们可以假设得到了上次的结果,继而往后运算。这就运用到了递归。
func countAndSay(n int) string { if n == 1 { return "1" } s := countAndSay(n - 1) i, res := 0, "" length := len(s) for j := 0; j < length; j++ { if s[j] != s[i] { res += strconv.Itoa(j-i) + string(s[i]) i = j } } res += strconv.Itoa(length-i) + string(s[i]) return res }
N 为给定的正整数,M 为生成的字符串中的最大长度
时间复杂度:O(N * M)
空间复杂度:O(M)
读到这里,这篇“Go Java算法之外观数列如何实现”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。