LeetCode——外观数列

156 阅读3分钟

「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。

前言

大家好,我是程序猿小白 GW_gw,很高兴能和大家一起学习进步。

以下内容部分来自于网络,如有侵权,请联系我删除,本文仅用于学习交流,不用作任何商业用途。

摘要

本文主要介绍LeetCode题目 外观数列 的一些解法和思路。

【题目】

给定一个正整数 n ,输出外观数列的第 n 项。

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。

你可以将其视作是由递归公式定义的数字字符串序列:

countAndSay(1) = "1" countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。 前五项如下:

  1. 1
  2. 11
  3. 21
  4. 1211
  5. 111221 第一项是数字 1

描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"

描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"

描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"

描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"

图片.png 题目链接:leetcode-cn.com/leetbook/re…

【递归解法】

【思路】 递归解法:

  1. 确定递归条件

  2. 进行递归

    1. 使用StringBuilder构建返回值。
    2. 定义计数器,用来统计相同字符的个数。
    3. 循环比较,如果相同就让计数器++,如果不相同就进行结果的构建,并且重置计数器。
    4. 最后要加上字符串最后的字符。(这一步如果有疑问就亲自试一下。)

【代码】

public String countAndSay(int n) {
    //递归结束条件
    if(n == 1){
        return "1";
    }
    //进行递归
    String s = countAndSay(n-1);
    //构建描述字符串
    //使用StringBuilder构建返回值
    StringBuilder res = new StringBuilder();
    //定义计数器
    char temp = s.charAt(0);
    int count = 1;
    for (int i = 1; i < s.length(); i++) {
        //如果是相同字符就找到最终相同的个数
        if(temp == s.charAt(i)){
            count++;
        }
        else{
            //如果不相同找到不相同的了就把前面的构建到返回结果上
            res.append(count).append(temp);
            //更新下一次需要记录的数量和字符
            count = 1;
            temp = s.charAt(i);
        }
    }
    //不要忘了加上最后比较的
    res.append(count).append(temp);
    return res.toString();
}

【非递归解法】

【思路】 和递归思路差不多,只不过我们只需要保存求得的上一次的字符即可。

  1. 构建返回值
  2. 循环根据上一个找到下一个
    1. 找下一个时每次要重置res。
    2. 定义计数器。
    3. 循环比较
    4. 加上最后的字符描述

构建字符描述的操作是相同的。

【代码】

public String countAndSay(int n) {
    /**
     * 非递归求解
     */
    //使用StringBuilder构建返回值,第一个是“1”
    StringBuilder res = new StringBuilder("1");

    for (int i = 1; i < n; i++) {
        //表示前一个
        String prev = res.toString();
        //找下一个时要重置res
        res = new StringBuilder();
        //定义计数器
        char temp = prev.charAt(0);
        int count = 1;
        for (int j = 1; j < prev.length(); j++) {
            //如果是相同字符就找到最终相同的个数
            if(temp == prev.charAt(j)){
                count++;
            }
            else{
                //如果不相同找到不相同的了就把前面的构建到返回结果上
                res.append(count).append(temp);
                //更新下一次需要记录的数量和字符
                count = 1;
                temp = prev.charAt(j);
            }
        }
        //不要忘了加上最后比较的
        res.append(count).append(temp);
    }
    System.out.println(res.toString());
    return res.toString();
}

小结

以上就是关于LeetCode外观数列这题的递归和非递归的解法,其中值得我们学习的是设置计数器来获得相同字符长度的思想,希望以上内容能对读者有所帮助,如有不正之处,欢迎留言指正。