题目

报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
1. 1
2. 11
3. 21
4. 1211
5. 111221

1 被读作 “one 1” (“一个一”) , 即 11。
11 被读作 “two 1s” (“两个一”), 即 21。
21 被读作 “one 2”, “one 1” (”一个二” , “一个一”) , 即 1211。
给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。
注意:整数顺序将表示为一个字符串。

以此类推:
6. 312211
7. 13112221

示例

  1. 输入: 1
  2. 输出: "1"
  3. 输入: 4
  4. 输出: "1211"

解析

Method Me
观察发现,连续的相同数字可被合并,不连续的数字需要单独拆开

当前项的值依赖于前一项,将前一项分割为字符串,遍历并记录连续相同的字符 X 的个数 continueSameNum,遇到不同的字符 Y,拼接此前连续的字符个数和字符,即 【continueSameNum + X】

  1. var getNumByRank = function (num) {
  2. if (num < 1) {
  3. return 'not is effect num'
  4. }
  5. let arr = new Array(num + 1).fill('0')
  6. arr[1] = '1'
  7. for (let i = 2, iLen = arr.length; i < iLen; i++) {
  8. let brr = arr[i - 1].split('')
  9. let str = ''
  10. let continueSameNum = 1
  11. for (let j = 0, jLen = brr.length; j < jLen; j++) {
  12. if (brr[j + 1] && brr[j + 1] === brr[j]) {
  13. continueSameNum += 1
  14. } else {
  15. str += continueSameNum + brr[j]
  16. continueSameNum = 1
  17. }
  18. }
  19. arr[i] = str
  20. }
  21. return arr[num]
  22. }

Method
思路分析:

实现方法一:递归
观察发现每一个结果与前一个结果相关,利用递归计算前一个值,知道返回1,再利用前一个值计算当前值

  1. var countAndSay = function(n) {
  2. if(n == 1) {
  3. return "1"
  4. } else {
  5. let str = countAndSay(n-1);
  6. let count = 1;
  7. let res = "";
  8. for (let i = 0;i < str.length;i++) {
  9. if (str[i] == str[i+1]) {
  10. count ++
  11. } else {
  12. res = res+count + str[i]
  13. count = 1
  14. }
  15. }
  16. return res
  17. }
  18. };

实现方法二:双指针
第一个指针记录值,第二个指针记录数量,同样利用前一个结果计算当前结果

  1. var countAndSay = function(n) {
  2. let num = "1";
  3. let sum = ""
  4. for(let l=0;l<n-1;l++){
  5. let sum = ""
  6. for(let i =0,j=0;i<num.length;){
  7. if(num[i]==num[i+j]){
  8. j++;
  9. }else{
  10. sum = sum +j+""+num[i];
  11. i += j;
  12. j=1;
  13. }
  14. }
  15. num = sum;
  16. }
  17. return num;
  18. };