题目描述:
报数序列是指一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
1. 1 2. 11 3. 21 4. 1211 5. 111221
1
被读作 ("一个一"
) , 即 11
。11
被读作 ("两个一"
), 即 21
。21
被读作("一个二"
, "一个一"
) , 即 1211
。
给定一个正整数 n ,输出报数序列的第 n 项。
注意:整数顺序将表示为一个字符串。
示例 :
输入: 1 输出: "1"
输入: 4 输出: "1211"
方法分析:
乍一看,这一道题有一点云里雾里,让我们来捋一捋。
首先,我们先写出1到10的报数数列:
1. 1 2. 11 3. 21 4. 1211 5. 111221 6. 312211 7. 13112221 8. 1113213211 9. 31131211131221 10. 13211311123113112211
仔细观察,从其中,能得出什么规律呢?
我们可以看到,报数数列的第n项,就是对第n-1项进行报数。换句话说,要知道报数数列的第n项,只需要知道其n-1项即可。比如说,我们要得到报数数列的第4项,就只需要知道第3项,要得到第3项,又只需要得到第2项,然后查找到第1项,就这样依次递归查找。
第4项 -->第3项 -->第2项 -->第1项
1211 <-- 21 <-- 11 <-- 1
这样一来,思路就清晰许多啦。
我们再结合具体的代码来分析。
代码实现:
var countAndSay = function(n) {
//结果字符串,输出报数数列的结果
var resultStr = "1";
for (var i = 1; i < n; i++) {
//定义重复次数,如“11”被读作“2个1”,其中的“2”就是重复次数
var repeatCount = 1;
var str = "";
for (var j = 0; j < resultStr.length; j++) {
//找出相邻相同项,增加重复次数
if (resultStr[j] == resultStr[j+1]) {
repeatCount++;
}else{
//存放每次迭代的结果,为上次结果 + 重复次数 + 当前字符
str += repeatCount + resultStr[j];
//重置重复次数
repeatCount = 1;
}
}
//迭代完毕,将str赋给resultStr
resultStr = str;
}
return resultStr;
};
代码解析:
我们定义了一个 countAndSay 函数,向其传入一个参数 n ,用来输出第 n 项的报数数列;在函数内部,我们首先定义了 resultStr 用来存放输出结果;然后迭代 n 项,依次得到从第1项到第n项的结果;每一次的结果,其组成为 上一次的结果 + 要迭代字符重复的次数 + 要跌倒字符本身。
比如说,对于输入 n = 4,其执行过程为:
- i = 1,j = 0,str = “11”,resultStr = “11”,
- i = 2,j = 0,由于resultStr[0] = resultStr[1],故repeatCount = 2 ,
- i = 2,j = 1,str = “21”,resultStr = “21”,
- i = 3,j = 0,str = “12”,
- i = 3,j = 1,str = “1211”,resultStr = “1211”,
- 结束所有迭代,返回结果"1211"
相关链接:https://leetcode-cn.com/problems/count-and-say/description/