$$ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Self-defined math definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Math symbol commands \newcommand{\intd}{\,{\rm d}} % Symbol 'd' used in integration, such as 'dx' \newcommand{\diff}{{\rm d}} % Symbol 'd' used in differentiation ... $$

38. 外观数列

题目描述查看:https://leetcode-cn.com/problems/count-and-say/

  题目的意思是新字符串是根据上一轮字符串按规则读取生成的。

  读取的规则是数字一样的数有几个,把数字的个数、数字写进新字符串。

  • 思路

分析题目可知,新字符串跟上一轮的字符串有关,要想求这一轮的字符串,必须先知道上一轮的字符串是啥,天然是个递归问题,可以使用动态规划来解。

设dp[i]为第i-1项的字符串,dp[i+1] 的值为遍历dp[i],并根据规则生成字符串。 

  • 边界条件

遍历字符串生成新字符串的过程,使用2个变量count和pre,count统计相似字符的个数,pre指向前一个字符。

for循环结束以后,最后的字符还没有写到builder中,循环结束后写。

 1 StringBuilder builder = new StringBuilder();
 2 char[] str = dp[i-1].toCharArray();
 3 int count = 1;
 4 char pre = str[0];
 5 for (int j = 1; j < str.length; j++) {
 6     if(str[j] == pre)count++;
 7     else{
 8         builder.append(count).append(pre);
 9         count = 1;
10         pre = str[j];
11     }
12 }
13 builder.append(count).append(pre);
14 dp[i] = builder.toString();
  •  代码

 1     public static String countAndSay(int n) {
 2         String[] dp = new String[n];
 3         dp[0] = "1";
 4         for (int i = 1; i < n; i++) {
 5             StringBuilder builder = new StringBuilder();
 6             char[] str = dp[i-1].toCharArray();
 7             int count = 1;
 8             char pre = str[0];
 9             for (int j = 1; j < str.length; j++) {
10                 if(str[j] == pre)count++;
11                 else{
12                     builder.append(count).append(pre);
13                     count = 1;
14                     pre = str[j];
15                 }
16             }
17             builder.append(count).append(pre);
18             dp[i] = builder.toString();
19         }
20         return dp[n-1];
21     }
  •  递归实现

方法作用,计算第n个外观数列。

参数,第几个外观数列。

结束条件,n==1时,返回"1";

 1     public static String countAndSay(int n) {
 2         if(n == 1)return "1";
 3         StringBuilder builder = new StringBuilder();
 4         char[] str = countAndSay(n-1).toCharArray();
 5         int count = 1;
 6         char pre = str[0];
 7         for (int j = 1; j < str.length; j++) {
 8             if(str[j] == pre)count++;
 9             else{
10                 builder.append(count).append(pre);
11                 count = 1;
12                 pre = str[j];
13             }
14         }
15         builder.append(count).append(pre);
16         return builder.toString();
17     }

 

posted @ 2020-03-30 13:07  V丶vvv  阅读(270)  评论(0编辑  收藏  举报