38、外观数列|38、外观数列 | 算法(leetode,附思维导图 + 全部解法)300题

零 标题:算法(leetode,附思维导图 + 全部解法)300题之(38)外观数列 码农三少 ,一个致力于编写极简、但齐全题解(算法)的博主 一 题目描述 38、外观数列|38、外观数列 | 算法(leetode,附思维导图 + 全部解法)300题
文章图片

38、外观数列|38、外观数列 | 算法(leetode,附思维导图 + 全部解法)300题
文章图片

38、外观数列|38、外观数列 | 算法(leetode,附思维导图 + 全部解法)300题
文章图片

二 解法总览(思维导图) 38、外观数列|38、外观数列 | 算法(leetode,附思维导图 + 全部解法)300题
文章图片

三 全部解法 1 方案1
1)代码:

// 方案1 “类似斐波那切数列,使用2个变量”// 思路: // 1)状态初始化 // 2)循环处理 n-1 次,不断处理 pre、now 值 // 2.1)根据 pre 值,计算出 now 值 // 2.2)将 now值 赋值给 pre 值,now 置为 '',接着进行下一次循环处理 ——> 根据 pre 值,计算出 now 值 // 3)返回结果 pre值 var countAndSay = function(n) { // 1)状态初始化 let pre = '1', now = ''; // 2)循环处理 n-1 次,不断处理 pre、now 值 for (let i = 0; i < n - 1; i++) { // 2.1)根据 pre 值,计算出 now 值 const preLength = pre.length; let count = 1; for (let j = 0; j < preLength; j++) { if (pre[j] === pre[j + 1]) { count++; } else { now += count + '' + pre[j]; count = 1; } }// 2.2)将 now值 赋值给 pre 值,now 置为 '',接着进行下一次循环处理 ——> 根据 pre 值,计算出 now 值 pre = now; now = ''; }// 3)返回结果 pre值 return pre; }

2 方案2
1)代码:
// 方案2 “递归 - 普通法” var countAndSay = function(n) { const dfs = (n) => { // 1)递归出口 if (n === 1) { return '1'; }// 2)递归主体 return dfs(n-1).replace(/(\d)\1*/g, item =>`${item.length}${item[0]}`); }; return dfs(n); }

3 方案3
1)代码:
// 方案3 “递归 - 简洁法” var countAndSay = function(n) { if (n === 1) { return '1'; }return countAndSay(n-1).replace(/(\d)\1*/g, item =>`${item.length}${item[0]}`); }

4 方案4
1)代码:
// 方案4 “正则 + 循环法”// 思路: // 1)状态初始化 // 2)循环处理:不断结合正则匹配情况,使用 replace 函数对 resStr 进行更新 // 2.1)注(核心):'111221'.match(/(\d)\1*/g) ,输出 ['111', '22', '1'] // 这样看下面代码就容易很多了, item 依次为 '111', '22', '1' 。 // 3)返回结果 resStr var countAndSay = function(n) { // 1)状态初始化 let resStr = '1'; // 2)循环处理:不断结合正则匹配情况,使用 replace 函数对 resStr 进行更新 for (let i = 1; i < n; i++){ // 2.1)注(核心):'111221'.match(/(\d)\1*/g) ,输出 ['111', '22', '1'] // 这样看下面代码就容易很多了, item 依次为 '111', '22', '1' 。 resStr = resStr.replace(/(\d)\1*/g, item =>`${item.length}${item[0]}`); }// 3)返回结果 resStr return resStr; };

5 方案5
【38、外观数列|38、外观数列 | 算法(leetode,附思维导图 + 全部解法)300题】1)代码:
// 方案5 “JS装X法:正则 + 递归 --> 1行代码”// 思路: // countAndSay(3) = countAndSay(2).replace(...) //= countAndSay(1).replace(...).replace(...) //= 1.replace(...).replace(...).replace(...) var countAndSay = function(n) { // 注:理解如下注释,代码就很容易了 // countAndSay(3) = countAndSay(2).replace(...) // = countAndSay(1).replace(...).replace(...) // = 1.replace(...).replace(...).replace(...) return n == 1 ? '1' : countAndSay(n-1).replace(/(\d)\1*/g, item =>`${item.length}${item[0]}`); };

    推荐阅读