首页 > 其他分享 >每日一练:LeeCode-38、外观数列【字符串】

每日一练:LeeCode-38、外观数列【字符串】

时间:2024-03-24 18:30:36浏览次数:38  
标签:count 字符 38 数列 StringBuilder say LeeCode res prev

给定一个正整数 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"

描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。

例如,数字字符串 "3322251" 的描述如下图:

示例 1:

输入:n = 1
输出:"1"
解释:这是一个基本样例。

示例 2:

输入:n = 4
输出:"1211"
解释:
countAndSay(1) = "1"
countAndSay(2) = 读 "1" = 一 个 1 = "11"
countAndSay(3) = 读 "11" = 二 个 1 = "21"
countAndSay(4) = 读 "21" = 一 个 2 + 一 个 1 = "12" + "11" = "1211"

提示:

  • 1 <= n <= 30

按照题意计算就好了,使用两个for循环,第2个循环不断的统计字符串中字符的个数,然后存储到一个StringBuilder中,然后这个StringBuilder会作为下一个统计开始的字符串……,重复上面的操作

StringBuilder:可以修改的字符串

互相转换:

StringBuilder——>String : toString()

String ——> StringBuilder : new StringBuilder (s)

class Solution {
    public String countAndSay(int n) {
        // 初始化当前项为 "1"
        StringBuilder res = new StringBuilder("1");
        StringBuilder prev; // 用于存储前一项序列
        int count; // 记录字符出现次数
        char say; // 记录当前正在统计的字符
        
        // 从第二项开始构建序列,直到第 n 项
        for (int i = 1; i < n; i++) {
            // 将当前项赋值给 prev
            prev = res;
            // 创建一个新的 StringBuilder 用于构建下一项序列
            res = new StringBuilder();
            // 初始化字符出现次数为 1,因为每个字符至少出现一次
            count = 1;
            // 获取前一项序列的第一个字符作为当前正在统计的字符
            say = prev.charAt(0);
            
            // 遍历前一项序列,从第二个字符开始
            for (int j = 1, len = prev.length(); j < len; j++) {
                // 如果当前字符与正在统计的字符不同,表示遇到了新的字符
                if (prev.charAt(j) != say) {
                    // 将之前统计的字符及其出现次数加入到 res 中
                    res.append(count).append(say);
                    // 将出现次数重新置为 1,因为遇到了新的字符
                    count = 1;
                    // 更新正在统计的字符为新的字符
                    say = prev.charAt(j);
                } else {
                    // 如果当前字符与正在统计的字符相同,则增加出现次数
                    count++;
                }
            }
            // 将最后一个字符及其出现次数加入到 res 中
            res.append(count).append(say);
        }
        // 返回第 n 项的描述
        return res.toString();
    }
}

  1. StringBuilder res = new StringBuilder("1");:首先创建一个 StringBuilder 对象 res,并将其初始化为 “1”。这个 StringBuilder 用来存储当前正在构建的序列。

  2. StringBuilder prev;:声明一个 StringBuilder 对象 prev,用来存储前一项的序列。

  3. int count;:用来记录字符出现的次数。

  4. char say;:用来记录当前正在统计的字符。

  5. for (int i = 1; i < n; i++) {:外层循环,从第二项开始构建序列,直到第 n 项。

  6. prev = res;:将当前构建好的序列 res 赋值给 prev,以备后用。

  7. res = new StringBuilder();:创建一个新的 StringBuilder 对象 res,用于构建下一项的序列。

  8. count = 1;:初始化 count 为 1,因为每个字符至少出现一次。

  9. say = prev.charAt(0);:获取前一项序列的第一个字符,作为当前正在统计的字符。

  10. for (int j = 1, len = prev.length(); j < len; j++) {:内层循环,遍历前一项的序列,从第二个字符开始。

  11. if (prev.charAt(j) != say) {:如果当前字符与正在统计的字符不相同,表示遇到了新的字符。

  12. res.append(count).append(say);:将之前统计的字符及其出现次数加入到 res 中。

  13. count = 1;:将 count 重新置为 1,因为遇到了新的字符。

  14. say = prev.charAt(j);:将正在统计的字符更新为新的字符。

  15. else { count++; }:如果当前字符与正在统计的字符相同,则增加 count。

  16. res.append(count).append(say);:将最后一个字符及其出现次数加入到 res 中。

  17. return res.toString();:将 StringBuilder 对象 res 转换为字符串并返回,即为第 n 项的描述。

这样,每次迭代都会根据前一项的描述构建出下一项的描述,直到得到第 n 项的描述为止。

标签:count,字符,38,数列,StringBuilder,say,LeeCode,res,prev
From: https://blog.csdn.net/kdzandlbj/article/details/136991989

相关文章

  • Programming Abstractions in C阅读笔记:p338-p346
    《ProgrammingAbstractionsinC》学习第80天,p338-p346,总计9页。一、技术总结栈的实现包括入栈、出栈、判断栈是否为满,判断栈是否为空等。作者结合RPN计算器来实现,稍显无聊。/**File:rpncalc.c*---------------*Thisprogramsimulatesanelectroniccalculatorth......
  • 接龙数列
    @目录一、题目描述二、算法简析三、本题代码一、题目描述P9242[蓝桥杯2023省B]接龙数列二、算法简析核心思想:动态规划题目要我们求删除数的最小个数。可以转变问题,求能形成的接龙数列的最大长度\(MaxLength\),\(n-MaxLength\)即为所求。由题意可知,我们只需要关注每......
  • CF938G-动态连通图最短xor路(线段树分治、并查集、线性基)
    link:https://codeforces.com/contest/938/problem/G[!Description]有一张连通的无向图简单图,三种操作:1、加边\((x,y,d)\)2、删边\((x,y)\)3、询问\(x\toy\)的路径中异或最小的路径(不一定是简单路径)保证每次操作后图是连通的\(1\leqn,m,q\leq2\times10^5\).这......
  • L2-038 病毒溯源
    #include<bits/stdc++.h>usingnamespacestd;vector<int>vec[10010],ans;//矩阵intvis[10010];intmaxLen=0;voiddfs(introot,vector<int>&v){ if(v.size()>maxLen){ ans.clear(); ans=v; maxLen=v.size(); } for(int......
  • BEE1038:经济学数据科学导论
    BEE1038:经济学数据科学导论在这项任务中,你将展示你对编程的理解和掌握Python使用数据科学工具。到第6/7周结束时,你将学到的东西几乎涵盖了你所需要的一切,你所学到的已经足够着手解决一些问题了。如果你被卡住了再读一遍笔记本。如果你仍然不确定,那就上网看看。谷歌和StackOverFl......
  • Leecode 杨辉三角Ⅱ
    Day7第二题我的思路和上一篇的杨辉三角一致,只不过将List获取层数的代码List.get(0).add()修改成数组classSolution{publicList<Integer>getRow(introwIndex){List<Integer>getRow=newArrayList<Integer>();int[][]dp=newint[ro......
  • CF938E-组合数
    link:https://codeforces.com/contest/938/problem/E题意:给一个序列\(a\),按如下方式计算\(f_a\):初始\(f_a=0,M=1\)对每个\(2\leqi\leqn\),如果\(a_M<a_i\),\(f_a\tof_a+a_M\),然后\(M=i\)对所有\(a\)的排列计算\(f_a\)并其在模\(10^9+7\)下的和。\(1\leqn\leq......
  • 泰波纳契数列
    实现泰波纳契数列的时候,用寻常的写法效率很低,classSolution:deftribonacci(self,n:int)->int:dp=[0foriinrange(n+1)]iflen(dp)==1:return0eliflen(dp)==2orlen(dp)==3:return1else......
  • Edu38
    基本情况C又不是正解,A甚至还加一,以后要考虑好再交。C.ConstructingTestsProblem-C-Codeforces为了更好的代码实现而非手算出解来推式子式子都推出来了。\(n^2-{\left\lfloor\frac{n}{m}\right\rfloor}^2=x\)myCode不知道怎么直接解,就写了一个\(\operatorname......
  • Leecode 二叉树的中序遍历
    Day6第三题这是一道让我崩溃的题,因为一个笔误root.right写成了root.left改了好久。classSolution{publicList<Integer>inorderTraversal(TreeNoderoot){List<Integer>listRoot=newArrayList<Integer>();if(root!=null){listRo......